Because the runtime is compacted into the standard library, functions
which are normally imported are actually local definitions. Use module
level named metadata to identify the module as being the swift standard
library. Refactor the condition slightly to improve code readability.
This addresses SR-7107!
The main part of this is to rewrite the small string literal-constructor to work with values (= shifting bytes) instead of setting bytes in memory.
This allows the compiler to fold away everything and end up with the optimal code for small string literals.
Making sure that makeIterator is always inlined, enables devirutalization of the iterator calls.
Inlining was not done with -Osize which resulted in pretty bad performance when iterating over an existential collection.
This saves a few instructions for some operations, like getting the count.
Also, it avoids the check for unwrapping the optional end pointer. For example, iterating over an unsafe buffer now has no overhead.
Also remove the _unboundedStartingAt initializer, which is not needed anymore.
Move the shifts to index creation time rather than index comparison
time. This seems to benefit micro benchmarks and cover up
inefficiencies in our generic index distance calculations.
Promote small-string to small-string comparison into the fast path for
equality and less-than.
Small ASCII strings that are not binary equal do not compare equal,
allowing us to early exit. Small ASCII strings otherwise compare
lexicographically, which we can call prior to jumping through a few
intermediaries.
Simplify String.Index by sinking transcoded offsets into the .utf8
variant. This is in preparation for a more resilient index type
capable of supporting existential string indices.
String.Index is 3 words in size, which means that Range<String.Index>
is 6, and Substring is 8 words total. This is pretty wasteful, so make
a very minor adjustment to the index cache's UTF-8 buffer to bring it
down to 2 words total.
Do other simplifications too.
This includes various revisions to the APIs landing in Swift 4.2, including:
- Random and other randomness APIs
- Hashable changes
- MemoryLayout.offset(of:)
As this function is generic, it makes a big difference when it can be specialized for concrete sequences, like arrays or unsafe buffers.
This fixes a performance regression of String(decoding:as:), e.g. when constructing a String from a byte buffer.
_StringGuts is not meant to be an abstraction across all the forms a
String may take. It's meant to abstract the book-keeping and the
visitor is a parameterization over operations.
Extract slow paths into non-inlinable functions so that fast-paths can
be faster and we don't pay the large code bloat for the Unicode
parsers.
Some tests proactively extended to highlight UTF8View of multiple
kinds of Strings.
Drop append-related @inlinable annotations for String, StringGuts,
StringStorage, and the Views. Drop several for larger operations, such
as case conversion. Drop as many as we can from StringGuts for now.
This is a small performance win; mainly I'm interested in simplifying the code so that there are fewer weird corners for bugs to creep in. Nonetheless, it seems to be about 5% faster with the (fast, dumb) LCG generator.