| Age | Commit message (Collapse) | Author | Lines |
|
In order to get rid of all range checks, the compiler needs to
explicitly see that the slices it iterates over are as long as the
loop variable upper bound.
This further improves the performance of slice comparison:
```
test u8_cmp ... bench: 4,761 ns/iter (+/- 1,203)
test u8_lt ... bench: 4,579 ns/iter (+/- 649)
test u8_partial_cmp ... bench: 4,768 ns/iter (+/- 761)
test u16_cmp ... bench: 4,607 ns/iter (+/- 580)
test u16_lt ... bench: 4,681 ns/iter (+/- 567)
test u16_partial_cmp ... bench: 4,607 ns/iter (+/- 967)
test u32_cmp ... bench: 4,448 ns/iter (+/- 891)
test u32_lt ... bench: 4,546 ns/iter (+/- 992)
test u32_partial_cmp ... bench: 4,415 ns/iter (+/- 646)
test u64_cmp ... bench: 4,380 ns/iter (+/- 1,184)
test u64_lt ... bench: 5,684 ns/iter (+/- 602)
test u64_partial_cmp ... bench: 4,663 ns/iter (+/- 1,158)
```
|
|
Instead of manually defining it, `partial_cmp` can simply wrap the
result of `cmp` for totally ordered types.
|
|
Reusing the same idea as in #26884, we can exploit the fact that the
length of slices is known, hence we can use a counted loop instead of
iterators, which means that we only need a single counter, instead of
having to increment and check one pointer for each iterator.
Using the generic implementation of the boolean comparison operators
(`lt`, `le`, `gt`, `ge`) provides further speedup for simple
types. This happens because the loop scans elements checking for
equality and dispatches to element comparison or length comparison
depending on the result of the prefix comparison.
```
test u8_cmp ... bench: 14,043 ns/iter (+/- 1,732)
test u8_lt ... bench: 16,156 ns/iter (+/- 1,864)
test u8_partial_cmp ... bench: 16,250 ns/iter (+/- 2,608)
test u16_cmp ... bench: 15,764 ns/iter (+/- 1,420)
test u16_lt ... bench: 19,833 ns/iter (+/- 2,826)
test u16_partial_cmp ... bench: 19,811 ns/iter (+/- 2,240)
test u32_cmp ... bench: 15,792 ns/iter (+/- 3,409)
test u32_lt ... bench: 18,577 ns/iter (+/- 2,075)
test u32_partial_cmp ... bench: 18,603 ns/iter (+/- 5,666)
test u64_cmp ... bench: 16,337 ns/iter (+/- 2,511)
test u64_lt ... bench: 18,074 ns/iter (+/- 7,914)
test u64_partial_cmp ... bench: 17,909 ns/iter (+/- 1,105)
```
```
test u8_cmp ... bench: 6,511 ns/iter (+/- 982)
test u8_lt ... bench: 6,671 ns/iter (+/- 919)
test u8_partial_cmp ... bench: 7,118 ns/iter (+/- 1,623)
test u16_cmp ... bench: 6,689 ns/iter (+/- 921)
test u16_lt ... bench: 6,712 ns/iter (+/- 947)
test u16_partial_cmp ... bench: 6,725 ns/iter (+/- 780)
test u32_cmp ... bench: 7,704 ns/iter (+/- 1,294)
test u32_lt ... bench: 7,611 ns/iter (+/- 3,062)
test u32_partial_cmp ... bench: 7,640 ns/iter (+/- 1,149)
test u64_cmp ... bench: 7,517 ns/iter (+/- 2,164)
test u64_lt ... bench: 7,579 ns/iter (+/- 1,048)
test u64_partial_cmp ... bench: 7,629 ns/iter (+/- 1,195)
```
|
|
Knowing the result of equality comparison can enable additional
optimizations in LLVM.
Additionally, this makes it obvious that `partial_cmp` on totally
ordered types cannot return `None`.
|
|
Fixes #28431
|
|
|
|
Closes https://github.com/rust-lang/rust/issues/26082
|
|
Overflows in integer pow() computations would be missed if they
preceded a 0 bit of the exponent being processed. This made
calls such as 2i32.pow(1024) not trigger an overflow.
Fixes #28012
|
|
This allows to skip the codegen for all the unneeded landing pads, reducing code size across the board by about 2-5%, depending on the crate. Compile times seem to be pretty unaffected though :-/
|
|
Unwinding across an FFI boundary is undefined behaviour, so we can mark
all external function as nounwind. The obvious exception are those
functions that actually perform the unwinding.
|
|
There is already a corresponding impl for `std::io::Write`. This change
will make the two traits more consistent.
|
|
The FCP is coming to a close and 1.4 is coming out soon, so this brings in the
libs team decision for all library features this cycle.
Stabilized APIs:
* `<Box<str>>::into_string`
* `Arc::downgrade`
* `Arc::get_mut`
* `Arc::make_mut`
* `Arc::try_unwrap`
* `Box::from_raw`
* `Box::into_raw`
* `CStr::to_str`
* `CStr::to_string_lossy`
* `CString::from_raw`
* `CString::into_raw`
* `IntoRawFd::into_raw_fd`
* `IntoRawFd`
* `IntoRawHandle::into_raw_handle`
* `IntoRawHandle`
* `IntoRawSocket::into_raw_socket`
* `IntoRawSocket`
* `Rc::downgrade`
* `Rc::get_mut`
* `Rc::make_mut`
* `Rc::try_unwrap`
* `Result::expect`
* `String::into_boxed_slice`
* `TcpSocket::read_timeout`
* `TcpSocket::set_read_timeout`
* `TcpSocket::set_write_timeout`
* `TcpSocket::write_timeout`
* `UdpSocket::read_timeout`
* `UdpSocket::set_read_timeout`
* `UdpSocket::set_write_timeout`
* `UdpSocket::write_timeout`
* `Vec::append`
* `Vec::split_off`
* `VecDeque::append`
* `VecDeque::retain`
* `VecDeque::split_off`
* `rc::Weak::upgrade`
* `rc::Weak`
* `slice::Iter::as_slice`
* `slice::IterMut::into_slice`
* `str::CharIndices::as_str`
* `str::Chars::as_str`
* `str::split_at_mut`
* `str::split_at`
* `sync::Weak::upgrade`
* `sync::Weak`
* `thread::park_timeout`
* `thread::sleep`
Deprecated APIs
* `BTreeMap::with_b`
* `BTreeSet::with_b`
* `Option::as_mut_slice`
* `Option::as_slice`
* `Result::as_mut_slice`
* `Result::as_slice`
* `f32::from_str_radix`
* `f64::from_str_radix`
Closes #27277
Closes #27718
Closes #27736
Closes #27764
Closes #27765
Closes #27766
Closes #27767
Closes #27768
Closes #27769
Closes #27771
Closes #27773
Closes #27775
Closes #27776
Closes #27785
Closes #27792
Closes #27795
Closes #27797
|
|
|
|
There is already a corresponding impl for `std::io::Write`. This change
will make the two traits more consistent.
|
|
|
|
The FCP is coming to a close and 1.4 is coming out soon, so this brings in the
libs team decision for all library features this cycle.
Stabilized APIs:
* `<Box<str>>::into_string`
* `Arc::downgrade`
* `Arc::get_mut`
* `Arc::make_mut`
* `Arc::try_unwrap`
* `Box::from_raw`
* `Box::into_raw`
* `CStr::to_str`
* `CStr::to_string_lossy`
* `CString::from_raw`
* `CString::into_raw`
* `IntoRawFd::into_raw_fd`
* `IntoRawFd`
* `IntoRawHandle::into_raw_handle`
* `IntoRawHandle`
* `IntoRawSocket::into_raw_socket`
* `IntoRawSocket`
* `Rc::downgrade`
* `Rc::get_mut`
* `Rc::make_mut`
* `Rc::try_unwrap`
* `Result::expect`
* `String::into_boxed_slice`
* `TcpSocket::read_timeout`
* `TcpSocket::set_read_timeout`
* `TcpSocket::set_write_timeout`
* `TcpSocket::write_timeout`
* `UdpSocket::read_timeout`
* `UdpSocket::set_read_timeout`
* `UdpSocket::set_write_timeout`
* `UdpSocket::write_timeout`
* `Vec::append`
* `Vec::split_off`
* `VecDeque::append`
* `VecDeque::retain`
* `VecDeque::split_off`
* `rc::Weak::upgrade`
* `rc::Weak`
* `slice::Iter::as_slice`
* `slice::IterMut::into_slice`
* `str::CharIndices::as_str`
* `str::Chars::as_str`
* `str::split_at_mut`
* `str::split_at`
* `sync::Weak::upgrade`
* `sync::Weak`
* `thread::park_timeout`
* `thread::sleep`
Deprecated APIs
* `BTreeMap::with_b`
* `BTreeSet::with_b`
* `Option::as_mut_slice`
* `Option::as_slice`
* `Result::as_mut_slice`
* `Result::as_slice`
* `f32::from_str_radix`
* `f64::from_str_radix`
Closes #27277
Closes #27718
Closes #27736
Closes #27764
Closes #27765
Closes #27766
Closes #27767
Closes #27768
Closes #27769
Closes #27771
Closes #27773
Closes #27775
Closes #27776
Closes #27785
Closes #27792
Closes #27795
Closes #27797
|
|
llvm seems to be having some trouble optimizing the iterator-based
string comparsion method into some equivalent to memcmp. This
explicitly calls out to the memcmp intrinisic in order to allow
llvm to generate better code. In some manual benchmarking, this
memcmp-based approach is 20 times faster than the iterator approach.
|
|
|
|
Generally, including everything that makes an unsafe block safe in the
block is good style. Since the assert! is what makes this safe, it
should go inside the block. I also added a few bits of whitespace.
|
|
Overflows in integer pow() computations would be missed if they
preceded a 0 bit of the exponent being processed. This made
calls such as 2i32.pow(1024) not trigger an overflow.
|
|
|
|
|
|
This commit is an implementation of [RFC 1212][rfc] which tweaks the behavior of
the `str::lines` and `BufRead::lines` iterators. Both iterators now account for
`\r\n` sequences in addition to `\n`, allowing for less surprising behavior
across platforms (especially in the `BufRead` case). Splitting *only* on the
`\n` character can still be achieved with `split('\n')` in both cases.
The `str::lines_any` function is also now deprecated as `str::lines` is a
drop-in replacement for it.
[rfc]: https://github.com/rust-lang/rfcs/blob/master/text/1212-line-endings.md
Closes #28032
|
|
Nothing too big, a few needless returns and a few closures eliminated (the latter may improve performance in some cases, at least compilation should be a bit faster).
|
|
Makes things more greppable.
This change was made automatically by clippy + bash scripts, though I will run test passes, please review carefully.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Specifically, `count`, `last`, and `nth` are implemented to use the
methods of the underlying slice iterator.
Partially closes #24214.
|
|
Do so by using the fact that fixed size arrays (like `[u8; 8]` can be coerced
to slices `&[u8]`, this is expressed through the trait `Unsize<[T]>` that all
fixed size arrays implement.
|
|
Specifically, `count`, `last`, and `nth` are implemented to use the
methods of the underlying slice iterator.
Partially closes #24214.
|
|
|
|
After submitting #28031, I ran a [script](https://gist.github.com/durka/a5243440697c780f669b) on the rest of src/ and found some anomalies. In this PR are the fixes that I thought were obvious (but I might be wrong!). The others I've submitted in issue #28037.
|
|
|
|
Fixes #27996.
Does this need any `#[stable]`/`#[unstable]` attributes?
|
|
It was pointing at the issue for `placement_new_protocol`.
|
|
|
|
Fixes #27996.
|
|
|
|
The implementation of the remainder operation belongs to
librustc_trans, but it is also stubbed out in libcore in order to
expose it as a trait on primitive types. Instead of exposing some
implementation details (like the upcast to `f64` in MSVC), use a
minimal implementation just like that of the `Div` trait.
|
|
|
|
|
|
The old code is temporarily needed in order to keep the MSVC build
working. It should be possible to remove this code after the bootstrap
compiler is updated to contain the MSVC workaround from #27875.
|
|
This does cause some breakage due to deficiencies in resolve -
`path::Components` is both an `Iterator` and implements `Eq`, `Ord`,
etc. If one calls e.g. `partial_cmp` on a `Components` and passes a
`&Components` intending to target the `PartialOrd` impl, the compiler
will select the `partial_cmp` from `Iterator` and then error out. I
doubt anyone will run into breakage from `Components` specifically, but
we should see if there are third party types that will run into issues.
`iter::order::equals` wasn't moved to `Iterator` since it's exactly the
same as `iter::order::eq` but with an `Eq` instead of `PartialEq` bound,
which doensn't seem very useful.
I also updated `le`, `gt`, etc to use `partial_cmp` which lets us drop
the extra `PartialEq` bound.
cc #27737
r? @alexcrichton
|
|
This does cause some breakage due to deficiencies in resolve -
`path::Components` is both an `Iterator` and implements `Eq`, `Ord`,
etc. If one calls e.g. `partial_cmp` on a `Components` and passes a
`&Components` intending to target the `PartialOrd` impl, the compiler
will select the `partial_cmp` from `Iterator` and then error out. I
doubt anyone will run into breakage from `Components` specifically, but
we should see if there are third party types that will run into issues.
`iter::order::equals` wasn't moved to `Iterator` since it's exactly the
same as `iter::order::eq` but with an `Eq` instead of `PartialEq` bound,
which doensn't seem very useful.
I also updated `le`, `gt`, etc to use `partial_cmp` which lets us drop
the extra `PartialEq` bound.
cc #27737
|
|
* Rename `Utf16Items` to `Utf16Decoder`. "Items" is meaningless.
* Generalize it to any `u16` iterator, not just `[u16].iter()`
* Make it yield `Result` instead of a custom `Utf16Item` enum that was isomorphic to `Result`. This enable using the `FromIterator for Result` impl.
* Replace `Utf16Item::to_char_lossy` with a `Utf16Decoder::lossy` iterator adaptor.
This is a [breaking change], but only for users of the unstable `rustc_unicode` crate.
I’d like this functionality to be stabilized and re-exported in `std` eventually, as the "low-level equivalent" of `String::from_utf16` and `String::from_utf16_lossy` like #27784 is the low-level equivalent of #27714.
CC @aturon, @alexcrichton
|