Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SR-106: New floating-point description implementation #15474

Merged
merged 12 commits into from
Apr 1, 2018

Conversation

tbkka
Copy link
Contributor

@tbkka tbkka commented Mar 24, 2018

This replaces the current implementation of description and
debugDescription for the standard floating-point types with a new
formatting routine that provides both improved performance and
better results.

Unlike the earlier code based on sprintf with a fixed number of
digits, this logic automatically chooses the optimal number of digits,
generating compact output where possible while ensuring round-trip
accuracy. As such, we can now use the exact same output for both description and
debugDescription (except of course that debugDescription provides
full detail for NaNs).

This resolves SR-106, SR-454, SR-491, SR-3131 and other related issues that have complained
about the floating-point description and debugDescription properties being inexact
and/or inconsistent.

Ergonomics

With the new code, the REPL generally prints the values you would expect.

(swift) 1.1
// r0 : Double = 1.1
(swift) (1.1).description
// r1 : String = "1.1"
(swift) 1e23
// r2 : Double = 1e+23
(swift) print("\(1e23.nextDown) \(1e23) \(1e23.nextUp)")
9.999999999999997e+22 1e+23 1.0000000000000001e+23
(swift) 1.100000000000001
// r3 : Double = 1.100000000000001
(swift) print("\(1.100000000000001)")
1.100000000000001
(swift) 1.0 / 10.0
// r4 : Double = 0.1
(swift) 1.0 / 10.0 + 1.0
// r5 : Double = 1.1

In comparison, the previous implementation routinely prints extraneous digits for debugDescription (used by the REPL) and omits significant digits in description (used by print):

Welcome to Apple Swift version 4.1 (swiftlang-902.0.38 clang-902.0.31). Type :help for assistance.
  1> 1.1
$R0: Double = 1.1000000000000001
  2> (1.1).description
$R1: String = "1.1"
  3> 1e23
$R2: Double = 9.9999999999999991E+22
  4> print("\(1e23.nextDown) \(1e23) \(1e23.nextUp)")
1e+23 1e+23 1e+23
  5> 1.100000000000001
$R3: Double = 1.100000000000001
  6> print("\(1.100000000000001)")
1.1
  7> 1.0 / 10.0
$R4: Double = 0.10000000000000001
  8> 1.0 / 10.0 + 1.0
$R5: Double = 1.1000000000000001

Of course, this only changes how the floating-point numbers are printed. The actual parsing, storage, and arithmetic operations are unaffected and are still subject to the same rounding issues common to all floating-point arithmetic.

About the Algorithm

The SwiftDtoa.c file here implements a variation of Florian Loitsch' Grisu2
algorithm with changes suggested by Andrysco, Jhala, and Lerner's 2016
paper describing Errol3.

The implementation is:

  • Fast. It uses only fixed-width integer arithmetic and has constant
    memory and time requirements.

  • Simple. It is only a little more complex than Loitsch' original
    implementation of Grisu2. The digit decomposition logic for double is
    less than 300 lines of standard C (half of which is common arithmetic
    support routines).

  • Always Accurate. Converting the decimal form back to binary using an
    accurate algorithm (such as Clinger's algorithm) will always yield exactly the
    original binary value. For the IEEE 754 formats, the round-trip will
    produce exactly the same bit pattern in memory. This is an essential
    requirement for debugging, logging, and JSON serialization.

  • Always Short. This always selects an accurate result with the minimum
    number of decimal digits. (So that 1.0 / 10.0 will always print 0.1.)

  • Always Close. Among all accurate, short results, this always chooses
    the result that is closest to the exact floating-point value. (In case
    of an exact tie, it rounds the last digit even.)

Performance

The graph below compares the new code (in green) to the performance of three other
popular algorithms. Note that this graph benchmarks just the underlying C code; the Swift
description logic must spend additional effort to allocate a returned String.

  • Dragon4 (in yellow) uses variable-length arithmetic in order to provide accurate results regardless of the number of digits requested. This causes it to become significantly slower when the input has a large positive or negative exponent. (The other algorithms here do not offer arbitrary numbers of digits, so can use much faster fixed-width arithmetic.) This is the algorithm commonly used by C standard library implementations of the printf family of functions.
  • Grisu3 + Dragon4 (in red) uses fast fixed-width arithmetic for 99% of values and falls back to Dragon4 about 1% of the time. Note the upper whisker that goes to the same height as Dragon4.
  • Errol4 (in blue) is a recent algorithm that uses multiple-precision floating-point arithmetic internally. It is the successor to Errol3 which partly inspired the new Swift implementation.
  • The new SwiftDtoa implementation (in green) is similar to the Errol algorithms but uses fixed-width integer arithmetic throughout. This gives it uniform fast performance regardless of the input value.

screen shot 2018-03-23 at 5 53 13 pm

This replaces the current implementation of `description` and
`debugDescription` for the standard floating-point types with a new
formatting routine based on a variation of Florian Loitsch' Grisu2
algorithm with changes suggested by Andrysco, Jhala, and Lerner's 2016
paper describing Errol3.

Unlike the earlier code based on `sprintf` with a fixed number of
digits, this version always chooses the optimal number of digits.  As
such, we can now use the exact same output for both `description` and
`debugDescription` (except of course that `debugDescription` provides
full detail for NaNs).

The implementation has been extensively commented; people familiar with
Grisu-style algorithms should find the code easy to understand.

This implementation is:

* Fast.  It uses only fixed-width integer arithmetic and has constant
  memory and time requirements.

* Simple. It is only a little more complex than Loitsch' original
  implementation of Grisu2.  The digit decomposition logic for double is
  less than 300 lines of standard C (half of which is common arithmetic
  support routines).

* Always Accurate. Converting the decimal form back to binary (using an
  accurate algorithm such as Clinger's) will always yield exactly the
  original binary value.  For the IEEE 754 formats, the round-trip will
  produce exactly the same bit pattern in memory.  This is an essential
  requirement for JSON serialization, debugging, and logging.

* Always Short.  This always selects an accurate result with the minimum
  number of decimal digits.  (So that `1.0 / 10.0` will always print
  `0.1`.)

* Always Close.  Among all accurate, short results, this always chooses
  the result that is closest to the exact floating-point value. (In case
  of an exact tie, it rounds the last digit even.)

This resolves SR-106 and related issues that have complained
about the floating-point `description` properties being inexact.
@tbkka
Copy link
Contributor Author

tbkka commented Mar 24, 2018

@swift-ci Please benchmark

@tbkka
Copy link
Contributor Author

tbkka commented Mar 24, 2018

I just noticed the bottom label got cut off on the graph. The horizontal axis is abs(decimal exponent) binned in groups of 50. So the first set of bars includes a sampling of numbers in 1e-50...1e+50, the second set covers 1e-100...1e-50 and 1e50...1e100, etc. The vertical axis is clock cycles.

@swift-ci
Copy link
Contributor

Build comment file:

Optimized (O)

Regression (4)
TEST OLD NEW DELTA SPEEDUP
StringInterpolationManySmallSegments 20988 23360 +11.3% 0.90x
DataCopyBytes 2480 2653 +7.0% 0.93x (?)
Histogram 867 919 +6.0% 0.94x
IterateData 1863 1969 +5.7% 0.95x (?)
Improvement (11)
TEST OLD NEW DELTA SPEEDUP
FloatingPointPrinting_Float80_description_uniform 1702150 42863 -97.5% 39.71x
FloatingPointPrinting_Float80_interpolated 1748725 80815 -95.4% 21.64x
FloatingPointPrinting_Double_description_uniform 134469 32734 -75.7% 4.11x
FloatingPointPrinting_Double_description_small 78933 31228 -60.4% 2.53x
FloatingPointPrinting_Float80_description_small 91164 39067 -57.1% 2.33x
FloatingPointPrinting_Double_interpolated 174847 74933 -57.1% 2.33x
FloatingPointPrinting_Float_description_small 41747 23017 -44.9% 1.81x
FloatingPointPrinting_Float_description_uniform 44681 25098 -43.8% 1.78x
FloatingPointPrinting_Float_interpolated 81869 62452 -23.7% 1.31x
DictionarySwapAt 8229 7116 -13.5% 1.16x (?)
StringBuilderWithLongSubstring 1393 1321 -5.2% 1.05x (?)
No Changes (410)
TEST OLD NEW DELTA SPEEDUP
AngryPhonebook 3519 3508 -0.3% 1.00x (?)
AnyHashableWithAClass 80731 81125 +0.5% 1.00x (?)
Array2D 2520 2525 +0.2% 1.00x (?)
ArrayAppend 1054 1065 +1.0% 0.99x (?)
ArrayAppendArrayOfInt 796 782 -1.8% 1.02x (?)
ArrayAppendAscii 13310 13310 +0.0% 1.00x
ArrayAppendFromGeneric 797 798 +0.1% 1.00x (?)
ArrayAppendGenericStructs 1410 1422 +0.9% 0.99x (?)
ArrayAppendLatin1 37646 37588 -0.2% 1.00x (?)
ArrayAppendLazyMap 1341 1339 -0.1% 1.00x (?)
ArrayAppendOptionals 1424 1401 -1.6% 1.02x (?)
ArrayAppendRepeatCol 1336 1339 +0.2% 1.00x (?)
ArrayAppendReserved 791 794 +0.4% 1.00x (?)
ArrayAppendSequence 1113 1119 +0.5% 0.99x (?)
ArrayAppendStrings 15150 15163 +0.1% 1.00x (?)
ArrayAppendToFromGeneric 791 797 +0.8% 0.99x (?)
ArrayAppendToGeneric 797 797 +0.0% 1.00x
ArrayAppendUTF16 37057 37240 +0.5% 1.00x (?)
ArrayInClass 85 85 +0.0% 1.00x
ArrayLiteral 0 0 +0.0% 1.00x
ArrayOfGenericPOD2 150 148 -1.3% 1.01x (?)
ArrayOfGenericRef 4374 4384 +0.2% 1.00x (?)
ArrayOfPOD 183 183 +0.0% 1.00x
ArrayOfRef 4361 4352 -0.2% 1.00x (?)
ArrayPlusEqualArrayOfInt 795 782 -1.6% 1.02x (?)
ArrayPlusEqualFiveElementCollection 6806 6746 -0.9% 1.01x (?)
ArrayPlusEqualSingleElementCollection 5218 5220 +0.0% 1.00x (?)
ArrayPlusEqualThreeElements 2010 2009 -0.0% 1.00x (?)
ArraySubscript 1555 1545 -0.6% 1.01x (?)
ArrayValueProp 8 8 +0.0% 1.00x
ArrayValueProp2 8 8 +0.0% 1.00x
ArrayValueProp3 8 8 +0.0% 1.00x
ArrayValueProp4 8 8 +0.0% 1.00x
BinaryFloatingPointConversionFromBinaryInteger 39 39 +0.0% 1.00x
BinaryFloatingPointPropertiesBinade 25 25 +0.0% 1.00x
BinaryFloatingPointPropertiesNextUp 28 28 +0.0% 1.00x
BinaryFloatingPointPropertiesUlp 35 35 +0.0% 1.00x
BitCount 202 202 +0.0% 1.00x
ByteSwap 100 101 +1.0% 0.99x (?)
COWTree 5476 5492 +0.3% 1.00x (?)
CSVParsing 825895 818333 -0.9% 1.01x (?)
CSVParsingAlt 731803 736731 +0.7% 0.99x (?)
CSVParsingAltIndices 338773 344632 +1.7% 0.98x (?)
CStringLongAscii 4734 4759 +0.5% 0.99x (?)
CStringLongNonAscii 2246 2238 -0.4% 1.00x (?)
CStringShortAscii 5528 5491 -0.7% 1.01x (?)
Calculator 670 670 +0.0% 1.00x
CaptureProp 4078 4079 +0.0% 1.00x (?)
ChainedFilterMap 1408 1407 -0.1% 1.00x (?)
CharIndexing_ascii_unicodeScalars 16972 16964 -0.0% 1.00x (?)
CharIndexing_ascii_unicodeScalars_Backwards 15651 15638 -0.1% 1.00x (?)
CharIndexing_chinese_unicodeScalars 12844 12843 -0.0% 1.00x (?)
CharIndexing_chinese_unicodeScalars_Backwards 11851 11842 -0.1% 1.00x (?)
CharIndexing_japanese_unicodeScalars 20314 20316 +0.0% 1.00x (?)
CharIndexing_japanese_unicodeScalars_Backwards 18737 18727 -0.1% 1.00x (?)
CharIndexing_korean_unicodeScalars 16449 16443 -0.0% 1.00x (?)
CharIndexing_korean_unicodeScalars_Backwards 15171 15170 -0.0% 1.00x (?)
CharIndexing_punctuatedJapanese_unicodeScalars 3061 3057 -0.1% 1.00x (?)
CharIndexing_punctuatedJapanese_unicodeScalars_Backwards 2831 2826 -0.2% 1.00x (?)
CharIndexing_punctuated_unicodeScalars 3830 3831 +0.0% 1.00x (?)
CharIndexing_punctuated_unicodeScalars_Backwards 3544 3536 -0.2% 1.00x (?)
CharIndexing_russian_unicodeScalars 14133 14129 -0.0% 1.00x (?)
CharIndexing_russian_unicodeScalars_Backwards 13041 13037 -0.0% 1.00x (?)
CharIndexing_tweet_unicodeScalars 33086 33089 +0.0% 1.00x (?)
CharIndexing_tweet_unicodeScalars_Backwards 30842 30841 -0.0% 1.00x (?)
CharIndexing_utf16_unicodeScalars 21566 21545 -0.1% 1.00x (?)
CharIndexing_utf16_unicodeScalars_Backwards 21449 21418 -0.1% 1.00x (?)
CharIteration_ascii_unicodeScalars 20770 20476 -1.4% 1.01x
CharIteration_ascii_unicodeScalars_Backwards 15570 15568 -0.0% 1.00x (?)
CharIteration_chinese_unicodeScalars 15759 15537 -1.4% 1.01x
CharIteration_chinese_unicodeScalars_Backwards 11790 11794 +0.0% 1.00x (?)
CharIteration_japanese_unicodeScalars 24830 24510 -1.3% 1.01x (?)
CharIteration_japanese_unicodeScalars_Backwards 18647 18635 -0.1% 1.00x (?)
CharIteration_korean_unicodeScalars 20154 19868 -1.4% 1.01x
CharIteration_korean_unicodeScalars_Backwards 15093 15098 +0.0% 1.00x (?)
CharIteration_punctuatedJapanese_unicodeScalars 3776 3696 -2.1% 1.02x
CharIteration_punctuatedJapanese_unicodeScalars_Backwards 2817 2816 -0.0% 1.00x (?)
CharIteration_punctuated_unicodeScalars 4704 4632 -1.5% 1.02x
CharIteration_punctuated_unicodeScalars_Backwards 3526 3525 -0.0% 1.00x (?)
CharIteration_russian_unicodeScalars 17327 17064 -1.5% 1.02x
CharIteration_russian_unicodeScalars_Backwards 12970 12972 +0.0% 1.00x (?)
CharIteration_tweet_unicodeScalars 41123 40448 -1.6% 1.02x
CharIteration_tweet_unicodeScalars_Backwards 30747 30753 +0.0% 1.00x (?)
CharIteration_utf16_unicodeScalars 27926 27654 -1.0% 1.01x (?)
CharIteration_utf16_unicodeScalars_Backwards 19144 19148 +0.0% 1.00x (?)
CharacterLiteralsLarge 5713 5713 +0.0% 1.00x
CharacterLiteralsSmall 217 217 +0.0% 1.00x
CharacterPropertiesFetch 4511 4540 +0.6% 0.99x (?)
CharacterPropertiesPrecomputed 1309 1287 -1.7% 1.02x (?)
CharacterPropertiesStashed 1446 1422 -1.7% 1.02x (?)
CharacterPropertiesStashedMemo 1700 1689 -0.6% 1.01x (?)
Chars 974 972 -0.2% 1.00x (?)
ClassArrayGetter 15 15 +0.0% 1.00x
Combos 460 459 -0.2% 1.00x (?)
DataAccessBytes 1138 1133 -0.4% 1.00x (?)
DataAppendArray 6032 6111 +1.3% 0.99x (?)
DataAppendBytes 5829 5835 +0.1% 1.00x (?)
DataAppendDataLargeToLarge 67800 68994 +1.8% 0.98x (?)
DataAppendDataLargeToMedium 36066 36461 +1.1% 0.99x (?)
DataAppendDataLargeToSmall 35318 35269 -0.1% 1.00x (?)
DataAppendDataMediumToLarge 38270 38696 +1.1% 0.99x (?)
DataAppendDataMediumToMedium 7637 7654 +0.2% 1.00x (?)
DataAppendDataMediumToSmall 6935 6786 -2.1% 1.02x (?)
DataAppendDataSmallToLarge 37609 37736 +0.3% 1.00x (?)
DataAppendDataSmallToMedium 7067 7180 +1.6% 0.98x (?)
DataAppendDataSmallToSmall 6626 6599 -0.4% 1.00x (?)
DataAppendSequence 18982 19143 +0.8% 0.99x (?)
DataCount 38 38 +0.0% 1.00x
DataMutateBytes 4257 4255 -0.0% 1.00x (?)
DataReplaceLarge 40346 42099 +4.3% 0.96x (?)
DataReplaceLargeBuffer 57422 56768 -1.1% 1.01x (?)
DataReplaceMedium 10926 10958 +0.3% 1.00x (?)
DataReplaceMediumBuffer 11359 11194 -1.5% 1.01x (?)
DataReplaceSmall 8442 8504 +0.7% 0.99x (?)
DataReplaceSmallBuffer 8545 8566 +0.2% 1.00x (?)
DataReset 3197 3165 -1.0% 1.01x (?)
DataSetCount 870 873 +0.3% 1.00x (?)
DataSubscript 234 235 +0.4% 1.00x (?)
DictOfArraysToArrayOfDicts 838 829 -1.1% 1.01x (?)
Dictionary 751 769 +2.4% 0.98x (?)
Dictionary2 1842 1836 -0.3% 1.00x (?)
Dictionary2OfObjects 3383 3382 -0.0% 1.00x (?)
Dictionary3 433 437 +0.9% 0.99x (?)
Dictionary3OfObjects 894 891 -0.3% 1.00x (?)
Dictionary4 855 832 -2.7% 1.03x (?)
Dictionary4OfObjects 985 941 -4.5% 1.05x (?)
DictionaryBridge 1891 1911 +1.1% 0.99x (?)
DictionaryCopy 118288 119704 +1.2% 0.99x (?)
DictionaryFilter 117745 118235 +0.4% 1.00x (?)
DictionaryGroup 268 269 +0.4% 1.00x (?)
DictionaryGroupOfObjects 2097 2105 +0.4% 1.00x (?)
DictionaryLiteral 2085 2084 -0.0% 1.00x (?)
DictionaryOfObjects 2656 2662 +0.2% 1.00x (?)
DictionaryRemove 5414 5403 -0.2% 1.00x (?)
DictionaryRemoveOfObjects 28444 28230 -0.8% 1.01x (?)
DictionarySubscriptDefaultMutation 334 348 +4.2% 0.96x
DictionarySubscriptDefaultMutationArray 674 681 +1.0% 0.99x (?)
DictionarySubscriptDefaultMutationArrayOfObjects 4213 4265 +1.2% 0.99x (?)
DictionarySubscriptDefaultMutationOfObjects 1944 1953 +0.5% 1.00x (?)
DictionarySwap 1463 1517 +3.7% 0.96x
DictionarySwapAtOfObjects 53154 53130 -0.0% 1.00x (?)
DictionarySwapOfObjects 9512 9425 -0.9% 1.01x (?)
DoubleWidthDivision 0 0 +0.0% 1.00x
DropFirstAnyCollection 83 84 +1.2% 0.99x (?)
DropFirstAnyCollectionLazy 60644 61069 +0.7% 0.99x (?)
DropFirstAnySeqCRangeIter 17413 17705 +1.7% 0.98x
DropFirstAnySeqCRangeIterLazy 17457 17696 +1.4% 0.99x
DropFirstAnySeqCntRange 28 28 +0.0% 1.00x
DropFirstAnySeqCntRangeLazy 28 28 +0.0% 1.00x
DropFirstAnySequence 4848 4911 +1.3% 0.99x (?)
DropFirstAnySequenceLazy 4858 4901 +0.9% 0.99x
DropFirstArray 35 35 +0.0% 1.00x
DropFirstArrayLazy 35 35 +0.0% 1.00x
DropFirstCountableRange 35 35 +0.0% 1.00x
DropFirstCountableRangeLazy 35 35 +0.0% 1.00x
DropFirstSequence 2680 2680 +0.0% 1.00x
DropFirstSequenceLazy 2774 2771 -0.1% 1.00x (?)
DropLastAnyCollection 31 30 -3.2% 1.03x (?)
DropLastAnyCollectionLazy 19930 20381 +2.3% 0.98x (?)
DropLastAnySeqCRangeIter 3551 3536 -0.4% 1.00x (?)
DropLastAnySeqCRangeIterLazy 3550 3538 -0.3% 1.00x (?)
DropLastAnySeqCntRange 13 13 +0.0% 1.00x
DropLastAnySeqCntRangeLazy 13 13 +0.0% 1.00x
DropLastAnySequence 4919 4899 -0.4% 1.00x (?)
DropLastAnySequenceLazy 4990 4968 -0.4% 1.00x (?)
DropLastCountableRange 11 11 +0.0% 1.00x
DropLastCountableRangeLazy 11 11 +0.0% 1.00x
DropLastSequence 634 632 -0.3% 1.00x (?)
DropLastSequenceLazy 633 632 -0.2% 1.00x (?)
DropWhileAnyCollection 107 107 +0.0% 1.00x
DropWhileAnyCollectionLazy 125 125 +0.0% 1.00x
DropWhileAnySeqCRangeIter 14257 14442 +1.3% 0.99x (?)
DropWhileAnySeqCRangeIterLazy 90 90 +0.0% 1.00x
DropWhileAnySeqCntRange 35 36 +2.9% 0.97x (?)
DropWhileAnySeqCntRangeLazy 90 90 +0.0% 1.00x
DropWhileAnySequence 5576 5648 +1.3% 0.99x (?)
DropWhileAnySequenceLazy 1856 1856 +0.0% 1.00x
DropWhileArrayLazy 88 88 +0.0% 1.00x
DropWhileCountableRange 35 35 +0.0% 1.00x
DropWhileCountableRangeLazy 105 105 +0.0% 1.00x
DropWhileSequence 1326 1325 -0.1% 1.00x (?)
DropWhileSequenceLazy 88 88 +0.0% 1.00x
EqualStringSubstring 47 47 +0.0% 1.00x
EqualSubstringString 47 47 +0.0% 1.00x
EqualSubstringSubstring 47 47 +0.0% 1.00x
EqualSubstringSubstringGenericEquatable 47 47 +0.0% 1.00x
ErrorHandling 2410 2458 +2.0% 0.98x (?)
ExclusivityGlobal 5 5 +0.0% 1.00x
ExclusivityIndependent 2 2 +0.0% 1.00x
FatCompactMap 194750 195380 +0.3% 1.00x (?)
FilterEvenUsingReduce 1306 1311 +0.4% 1.00x (?)
FilterEvenUsingReduceInto 146 145 -0.7% 1.01x (?)
FrequenciesUsingReduce 7249 7015 -3.2% 1.03x (?)
FrequenciesUsingReduceInto 3692 3689 -0.1% 1.00x (?)
Hanoi 2103 2102 -0.0% 1.00x (?)
HashTest 1760 1774 +0.8% 0.99x (?)
Integrate 342 342 +0.0% 1.00x
Join 349 345 -1.1% 1.01x (?)
LazilyFilteredArrayContains 36654 36664 +0.0% 1.00x (?)
LazilyFilteredArrays 65160 65224 +0.1% 1.00x (?)
LazilyFilteredRange 3833 3841 +0.2% 1.00x (?)
LessSubstringSubstring 47 47 +0.0% 1.00x
LessSubstringSubstringGenericComparable 50 49 -2.0% 1.02x (?)
LinkedList 7539 7540 +0.0% 1.00x (?)
LuhnAlgoEager 539 536 -0.6% 1.01x (?)
LuhnAlgoLazy 535 536 +0.2% 1.00x (?)
MapReduce 408 409 +0.2% 1.00x (?)
MapReduceAnyCollection 400 400 +0.0% 1.00x
MapReduceAnyCollectionShort 2262 2264 +0.1% 1.00x (?)
MapReduceClass 3015 3009 -0.2% 1.00x (?)
MapReduceClassShort 4566 4567 +0.0% 1.00x (?)
MapReduceLazyCollection 13 13 +0.0% 1.00x
MapReduceLazyCollectionShort 35 35 +0.0% 1.00x
MapReduceLazySequence 86 86 +0.0% 1.00x
MapReduceSequence 433 438 +1.2% 0.99x (?)
MapReduceShort 1991 2026 +1.8% 0.98x (?)
MapReduceShortString 21 21 +0.0% 1.00x
MapReduceString 79 79 +0.0% 1.00x
Memset 214 214 +0.0% 1.00x
MonteCarloE 10776 10774 -0.0% 1.00x (?)
MonteCarloPi 42752 42810 +0.1% 1.00x (?)
NSDictionaryCastToSwift 5443 5350 -1.7% 1.02x (?)
NSError 301 301 +0.0% 1.00x
NSStringConversion 392 392 +0.0% 1.00x
NibbleSort 3677 3677 +0.0% 1.00x
NopDeinit 32093 32072 -0.1% 1.00x (?)
ObjectAllocation 132 131 -0.8% 1.01x (?)
ObjectiveCBridgeFromNSArrayAnyObject 23628 23216 -1.7% 1.02x (?)
ObjectiveCBridgeFromNSArrayAnyObjectForced 4591 4473 -2.6% 1.03x (?)
ObjectiveCBridgeFromNSArrayAnyObjectToString 41361 42931 +3.8% 0.96x (?)
ObjectiveCBridgeFromNSArrayAnyObjectToStringForced 40090 39579 -1.3% 1.01x (?)
ObjectiveCBridgeFromNSDictionaryAnyObject 102300 103290 +1.0% 0.99x (?)
ObjectiveCBridgeFromNSSetAnyObject 48335 49080 +1.5% 0.98x (?)
ObjectiveCBridgeFromNSSetAnyObjectForced 4121 4117 -0.1% 1.00x (?)
ObjectiveCBridgeFromNSSetAnyObjectToString 76102 79311 +4.2% 0.96x (?)
ObjectiveCBridgeFromNSString 1326 1358 +2.4% 0.98x (?)
ObjectiveCBridgeFromNSStringForced 2436 2433 -0.1% 1.00x (?)
ObjectiveCBridgeStubDataAppend 11071 11052 -0.2% 1.00x (?)
ObjectiveCBridgeStubDateMutation 400 400 +0.0% 1.00x
ObjectiveCBridgeStubFromArrayOfNSString 29371 30164 +2.7% 0.97x (?)
ObjectiveCBridgeStubFromNSDate 5918 5908 -0.2% 1.00x (?)
ObjectiveCBridgeStubFromNSString 954 956 +0.2% 1.00x (?)
ObjectiveCBridgeStubFromNSStringRef 161 161 +0.0% 1.00x
ObjectiveCBridgeStubNSDataAppend 2489 2472 -0.7% 1.01x (?)
ObjectiveCBridgeStubNSDateMutationRef 13158 13311 +1.2% 0.99x (?)
ObjectiveCBridgeStubToArrayOfNSString 27848 28120 +1.0% 0.99x (?)
ObjectiveCBridgeStubToNSDate 15164 14607 -3.7% 1.04x (?)
ObjectiveCBridgeStubToNSDateRef 3426 3410 -0.5% 1.00x (?)
ObjectiveCBridgeStubToNSString 1520 1503 -1.1% 1.01x (?)
ObjectiveCBridgeStubToNSStringRef 115 115 +0.0% 1.00x
ObjectiveCBridgeStubURLAppendPath 350453 335819 -4.2% 1.04x (?)
ObjectiveCBridgeStubURLAppendPathRef 349626 343303 -1.8% 1.02x (?)
ObjectiveCBridgeToNSArray 28739 28611 -0.4% 1.00x (?)
ObjectiveCBridgeToNSDictionary 42133 41902 -0.5% 1.01x (?)
ObjectiveCBridgeToNSSet 32864 32747 -0.4% 1.00x (?)
ObjectiveCBridgeToNSString 1294 1296 +0.2% 1.00x (?)
ObserverClosure 2169 2172 +0.1% 1.00x (?)
ObserverForwarderStruct 1244 1243 -0.1% 1.00x (?)
ObserverPartiallyAppliedMethod 3753 3745 -0.2% 1.00x (?)
ObserverUnappliedMethod 2586 2583 -0.1% 1.00x (?)
OpenClose 120 120 +0.0% 1.00x
PartialApplyDynamicType 0 0 +0.0% 1.00x
Phonebook 3844 3833 -0.3% 1.00x (?)
PointerArithmetics 31505 31488 -0.1% 1.00x (?)
PolymorphicCalls 25 25 +0.0% 1.00x
PopFrontArray 1800 1802 +0.1% 1.00x (?)
PopFrontArrayGeneric 1806 1805 -0.1% 1.00x (?)
PopFrontUnsafePointer 8652 8653 +0.0% 1.00x (?)
PrefixAnyCollection 84 83 -1.2% 1.01x
PrefixAnyCollectionLazy 60681 61425 +1.2% 0.99x (?)
PrefixAnySeqCRangeIter 13758 13753 -0.0% 1.00x (?)
PrefixAnySeqCRangeIterLazy 13767 13758 -0.1% 1.00x (?)
PrefixAnySeqCntRange 28 28 +0.0% 1.00x
PrefixAnySeqCntRangeLazy 28 28 +0.0% 1.00x
PrefixAnySequence 4216 4248 +0.8% 0.99x (?)
PrefixAnySequenceLazy 4239 4251 +0.3% 1.00x (?)
PrefixArray 35 35 +0.0% 1.00x
PrefixArrayLazy 35 35 +0.0% 1.00x
PrefixCountableRange 35 35 +0.0% 1.00x
PrefixCountableRangeLazy 35 35 +0.0% 1.00x
PrefixSequence 1325 1325 +0.0% 1.00x
PrefixSequenceLazy 1413 1413 +0.0% 1.00x
PrefixWhileAnyCollection 154 154 +0.0% 1.00x
PrefixWhileAnyCollectionLazy 90 90 +0.0% 1.00x
PrefixWhileAnySeqCRangeIter 8692 8679 -0.1% 1.00x (?)
PrefixWhileAnySeqCRangeIterLazy 24 24 +0.0% 1.00x
PrefixWhileAnySeqCntRange 60 59 -1.7% 1.02x (?)
PrefixWhileAnySeqCntRangeLazy 24 24 +0.0% 1.00x
PrefixWhileAnySequence 9890 9854 -0.4% 1.00x (?)
PrefixWhileAnySequenceLazy 1393 1393 +0.0% 1.00x
PrefixWhileArray 88 88 +0.0% 1.00x
PrefixWhileArrayLazy 70 70 +0.0% 1.00x
PrefixWhileCountableRange 35 35 +0.0% 1.00x
PrefixWhileCountableRangeLazy 35 35 +0.0% 1.00x
PrefixWhileSequence 361 361 +0.0% 1.00x
PrefixWhileSequenceLazy 52 52 +0.0% 1.00x
Prims 1190 1162 -2.4% 1.02x (?)
PrimsSplit 1197 1164 -2.8% 1.03x (?)
QueueConcrete 1131 1133 +0.2% 1.00x (?)
QueueGeneric 1136 1136 +0.0% 1.00x
RC4 162 162 +0.0% 1.00x
RGBHistogram 3874 3906 +0.8% 0.99x (?)
RGBHistogramOfObjects 25315 25376 +0.2% 1.00x (?)
RangeAssignment 336 336 +0.0% 1.00x
RangeIterationSigned 171 171 +0.0% 1.00x
RangeIterationSigned64 200 200 +0.0% 1.00x
RangeIterationUnsigned 200 200 +0.0% 1.00x
RangeReplaceableCollectionPlusDefault 905 902 -0.3% 1.00x (?)
RecursiveOwnedParameter 115 115 +0.0% 1.00x
RemoveWhereFilterInts 45 45 +0.0% 1.00x
RemoveWhereFilterString 372 374 +0.5% 0.99x (?)
RemoveWhereFilterStrings 432 432 +0.0% 1.00x
RemoveWhereMoveInts 14 14 +0.0% 1.00x
RemoveWhereMoveStrings 701 701 +0.0% 1.00x
RemoveWhereQuadraticInts 1290 1290 +0.0% 1.00x
RemoveWhereQuadraticString 490 490 +0.0% 1.00x
RemoveWhereQuadraticStrings 2753 2751 -0.1% 1.00x (?)
RemoveWhereSwapInts 19 19 +0.0% 1.00x
RemoveWhereSwapStrings 853 853 +0.0% 1.00x
ReversedArray 57 57 +0.0% 1.00x
ReversedBidirectional 15955 15901 -0.3% 1.00x (?)
ReversedDictionary 334 345 +3.3% 0.97x (?)
RomanNumbers 134484 134741 +0.2% 1.00x (?)
SequenceAlgosAnySequence 9620 9362 -2.7% 1.03x
SequenceAlgosArray 1565 1574 +0.6% 0.99x (?)
SequenceAlgosContiguousArray 1567 1574 +0.4% 1.00x (?)
SequenceAlgosList 1350 1355 +0.4% 1.00x (?)
SequenceAlgosRange 2576 2576 +0.0% 1.00x
SequenceAlgosUnfoldSequence 1079 1079 +0.0% 1.00x
SetExclusiveOr 6547 6574 +0.4% 1.00x (?)
SetExclusiveOr_OfObjects 14584 14629 +0.3% 1.00x (?)
SetIntersect 995 985 -1.0% 1.01x (?)
SetIntersect_OfObjects 2334 2318 -0.7% 1.01x (?)
SetIsSubsetOf 386 385 -0.3% 1.00x (?)
SetIsSubsetOf_OfObjects 535 535 +0.0% 1.00x
SetUnion 5602 5561 -0.7% 1.01x (?)
SetUnion_OfObjects 12023 12127 +0.9% 0.99x (?)
SevenBoom 1490 1487 -0.2% 1.00x (?)
Sim2DArray 417 417 +0.0% 1.00x
SortLargeExistentials 5533 5485 -0.9% 1.01x (?)
SortLettersInPlace 995 995 +0.0% 1.00x
SortSortedStrings 816 812 -0.5% 1.00x (?)
SortStrings 1608 1598 -0.6% 1.01x (?)
SortStringsUnicode 2339 2330 -0.4% 1.00x (?)
StackPromo 22127 22853 +3.3% 0.97x (?)
StaticArray 9 9 +0.0% 1.00x
StrComplexWalk 1559 1560 +0.1% 1.00x (?)
StrToInt 1541 1519 -1.4% 1.01x
StringAdder 4181 4192 +0.3% 1.00x (?)
StringBuilder 1588 1590 +0.1% 1.00x (?)
StringBuilderLong 1101 1077 -2.2% 1.02x (?)
StringComparison_abnormal 777 805 +3.6% 0.97x (?)
StringComparison_ascii 865 865 +0.0% 1.00x
StringComparison_emoji 767 768 +0.1% 1.00x (?)
StringComparison_fastPrenormal 686 684 -0.3% 1.00x (?)
StringComparison_latin1 532 532 +0.0% 1.00x
StringComparison_longSharedPrefix 881 874 -0.8% 1.01x (?)
StringComparison_nonBMPSlowestPrenormal 1509 1494 -1.0% 1.01x (?)
StringComparison_slowerPrenormal 1566 1588 +1.4% 0.99x
StringComparison_zalgo 122629 122589 -0.0% 1.00x (?)
StringEdits 148950 149014 +0.0% 1.00x (?)
StringEnumRawValueInitialization 1016 1015 -0.1% 1.00x (?)
StringEqualPointerComparison 286 286 +0.0% 1.00x
StringFromLongWholeSubstring 21 21 +0.0% 1.00x
StringFromLongWholeSubstringGeneric 95 96 +1.1% 0.99x (?)
StringHasPrefixAscii 1746 1746 +0.0% 1.00x
StringHasPrefixUnicode 110038 109662 -0.3% 1.00x (?)
StringHasSuffixAscii 1889 1890 +0.1% 1.00x (?)
StringHasSuffixUnicode 112673 112482 -0.2% 1.00x (?)
StringInterpolation 10092 10127 +0.3% 1.00x (?)
StringInterpolationSmall 8545 8686 +1.7% 0.98x (?)
StringMatch 9756 9787 +0.3% 1.00x (?)
StringRemoveDupes 1357 1365 +0.6% 0.99x (?)
StringUTF16Builder 2478 2482 +0.2% 1.00x (?)
StringUTF16SubstringBuilder 5373 5285 -1.6% 1.02x (?)
StringWalk 1411 1421 +0.7% 0.99x (?)
StringWithCString 41311 41311 +0.0% 1.00x
StringWordBuilder 2378 2395 +0.7% 0.99x (?)
StringWordBuilderReservingCapacity 2055 2072 +0.8% 0.99x
SubstringComparable 49 49 +0.0% 1.00x
SubstringEqualString 532 520 -2.3% 1.02x (?)
SubstringEquatable 1326 1307 -1.4% 1.01x (?)
SubstringFromLongString 10 10 +0.0% 1.00x
SubstringFromLongStringGeneric 74 74 +0.0% 1.00x
SuffixAnyCollection 31 31 +0.0% 1.00x
SuffixAnyCollectionLazy 20238 20179 -0.3% 1.00x (?)
SuffixAnySeqCRangeIter 3776 3764 -0.3% 1.00x (?)
SuffixAnySeqCRangeIterLazy 3764 3772 +0.2% 1.00x (?)
SuffixAnySeqCntRange 20 21 +5.0% 0.95x (?)
SuffixAnySeqCntRangeLazy 20 20 +0.0% 1.00x
SuffixAnySequence 4907 4886 -0.4% 1.00x (?)
SuffixAnySequenceLazy 5033 5012 -0.4% 1.00x (?)
SuffixCountableRange 11 11 +0.0% 1.00x
SuffixCountableRangeLazy 11 11 +0.0% 1.00x
SuffixSequence 3666 3651 -0.4% 1.00x (?)
SuffixSequenceLazy 3665 3652 -0.4% 1.00x (?)
SumUsingReduce 101 101 +0.0% 1.00x
SumUsingReduceInto 97 97 +0.0% 1.00x
SuperChars 40391 40344 -0.1% 1.00x (?)
TwoSum 1722 1744 +1.3% 0.99x (?)
TypeFlood 0 0 +0.0% 1.00x
UTF8Decode 295 295 +0.0% 1.00x
Walsh 404 403 -0.2% 1.00x (?)
WordCountHistogramASCII 7550 7457 -1.2% 1.01x (?)
WordCountHistogramUTF16 12937 12966 +0.2% 1.00x (?)
WordCountUniqueASCII 2670 2781 +4.2% 0.96x (?)
WordCountUniqueUTF16 6818 6864 +0.7% 0.99x (?)
WordSplitASCII 19393 19264 -0.7% 1.01x (?)
WordSplitUTF16 20921 20986 +0.3% 1.00x (?)
XorLoop 401 401 +0.0% 1.00x

Unoptimized (Onone)

Regression (6)
TEST OLD NEW DELTA SPEEDUP
StringInterpolationManySmallSegments 22461 25008 +11.3% 0.90x
Combos 2068 2244 +8.5% 0.92x (?)
CharacterPropertiesStashedMemo 5139 5548 +8.0% 0.93x (?)
DataAppendDataSmallToSmall 5609 5986 +6.7% 0.94x (?)
DataReplaceMedium 8868 9343 +5.4% 0.95x (?)
ObjectiveCBridgeStubToNSDate 15240 16047 +5.3% 0.95x (?)
Improvement (16)
TEST OLD NEW DELTA SPEEDUP
FloatingPointPrinting_Float80_description_uniform 1745707 77647 -95.6% 22.48x
FloatingPointPrinting_Float80_interpolated 1835988 144753 -92.1% 12.68x
FloatingPointPrinting_Double_description_uniform 151188 47398 -68.6% 3.19x
FloatingPointPrinting_Double_description_small 81157 33175 -59.1% 2.45x
FloatingPointPrinting_Float80_description_small 97005 41538 -57.2% 2.34x
FloatingPointPrinting_Double_interpolated 247378 123529 -50.1% 2.00x
FloatingPointPrinting_Float_description_small 42664 24233 -43.2% 1.76x
FloatingPointPrinting_Float_description_uniform 56238 36927 -34.3% 1.52x
FloatingPointPrinting_Float_interpolated 137261 107199 -21.9% 1.28x
DataReplaceMediumBuffer 12636 11253 -10.9% 1.12x
DataReplaceSmallBuffer 8954 8243 -7.9% 1.09x (?)
ObjectiveCBridgeStubNSDateMutationRef 16213 15106 -6.8% 1.07x (?)
BinaryFloatingPointConversionFromBinaryInteger 5921 5572 -5.9% 1.06x (?)
DataSetCount 600 565 -5.8% 1.06x (?)
WordSplitASCII 23527 22312 -5.2% 1.05x (?)
ObjectiveCBridgeStubURLAppendPath 365300 347542 -4.9% 1.05x (?)
No Changes (403)
TEST OLD NEW DELTA SPEEDUP
AngryPhonebook 4969 5029 +1.2% 0.99x (?)
AnyHashableWithAClass 97918 98234 +0.3% 1.00x (?)
Array2D 648683 648136 -0.1% 1.00x (?)
ArrayAppend 4321 4327 +0.1% 1.00x (?)
ArrayAppendArrayOfInt 862 865 +0.3% 1.00x (?)
ArrayAppendAscii 38767 38832 +0.2% 1.00x (?)
ArrayAppendFromGeneric 871 870 -0.1% 1.00x (?)
ArrayAppendGenericStructs 1504 1475 -1.9% 1.02x (?)
ArrayAppendLatin1 62959 63507 +0.9% 0.99x (?)
ArrayAppendLazyMap 164116 163237 -0.5% 1.01x
ArrayAppendOptionals 1498 1500 +0.1% 1.00x (?)
ArrayAppendRepeatCol 161324 158619 -1.7% 1.02x
ArrayAppendReserved 3937 3935 -0.1% 1.00x (?)
ArrayAppendSequence 100365 98638 -1.7% 1.02x
ArrayAppendStrings 15314 15325 +0.1% 1.00x (?)
ArrayAppendToFromGeneric 867 864 -0.3% 1.00x
ArrayAppendToGeneric 872 868 -0.5% 1.00x (?)
ArrayAppendUTF16 61249 61173 -0.1% 1.00x (?)
ArrayInClass 6143 6171 +0.5% 1.00x (?)
ArrayLiteral 1793 1794 +0.1% 1.00x (?)
ArrayOfGenericPOD2 1128 1128 +0.0% 1.00x
ArrayOfGenericRef 10740 10760 +0.2% 1.00x (?)
ArrayOfPOD 844 845 +0.1% 1.00x (?)
ArrayOfRef 9926 9849 -0.8% 1.01x (?)
ArrayPlusEqualArrayOfInt 862 864 +0.2% 1.00x (?)
ArrayPlusEqualFiveElementCollection 229643 229839 +0.1% 1.00x (?)
ArrayPlusEqualSingleElementCollection 227341 227668 +0.1% 1.00x (?)
ArrayPlusEqualThreeElements 9211 9189 -0.2% 1.00x (?)
ArraySubscript 108347 108192 -0.1% 1.00x (?)
ArrayValueProp 3708 3686 -0.6% 1.01x (?)
ArrayValueProp2 14932 14801 -0.9% 1.01x
ArrayValueProp3 4260 4260 +0.0% 1.00x
ArrayValueProp4 4134 4149 +0.4% 1.00x (?)
BinaryFloatingPointPropertiesBinade 88 88 +0.0% 1.00x
BinaryFloatingPointPropertiesNextUp 128 128 +0.0% 1.00x
BinaryFloatingPointPropertiesUlp 128 131 +2.3% 0.98x
BitCount 8998 8997 -0.0% 1.00x (?)
ByteSwap 9323 9272 -0.5% 1.01x (?)
COWTree 11394 11566 +1.5% 0.99x (?)
CSVParsing 2386259 2382113 -0.2% 1.00x (?)
CSVParsingAlt 1333131 1378571 +3.4% 0.97x (?)
CSVParsingAltIndices 2129220 2173267 +2.1% 0.98x (?)
CStringLongAscii 4526 4534 +0.2% 1.00x (?)
CStringLongNonAscii 2223 2243 +0.9% 0.99x (?)
CStringShortAscii 7739 7689 -0.6% 1.01x (?)
Calculator 1229 1229 +0.0% 1.00x
CaptureProp 234730 241578 +2.9% 0.97x
ChainedFilterMap 226362 223942 -1.1% 1.01x (?)
CharIndexing_ascii_unicodeScalars 298891 299193 +0.1% 1.00x (?)
CharIndexing_ascii_unicodeScalars_Backwards 338017 342642 +1.4% 0.99x (?)
CharIndexing_chinese_unicodeScalars 226395 229026 +1.2% 0.99x (?)
CharIndexing_chinese_unicodeScalars_Backwards 255795 261338 +2.2% 0.98x (?)
CharIndexing_japanese_unicodeScalars 358827 361258 +0.7% 0.99x (?)
CharIndexing_japanese_unicodeScalars_Backwards 411956 414945 +0.7% 0.99x (?)
CharIndexing_korean_unicodeScalars 292064 293108 +0.4% 1.00x (?)
CharIndexing_korean_unicodeScalars_Backwards 329028 330901 +0.6% 0.99x (?)
CharIndexing_punctuatedJapanese_unicodeScalars 52586 53162 +1.1% 0.99x (?)
CharIndexing_punctuatedJapanese_unicodeScalars_Backwards 59312 60826 +2.6% 0.98x (?)
CharIndexing_punctuated_unicodeScalars 66346 66629 +0.4% 1.00x (?)
CharIndexing_punctuated_unicodeScalars_Backwards 74112 75500 +1.9% 0.98x (?)
CharIndexing_russian_unicodeScalars 248945 251881 +1.2% 0.99x (?)
CharIndexing_russian_unicodeScalars_Backwards 283196 286640 +1.2% 0.99x (?)
CharIndexing_tweet_unicodeScalars 594162 596384 +0.4% 1.00x (?)
CharIndexing_tweet_unicodeScalars_Backwards 671996 681515 +1.4% 0.99x (?)
CharIndexing_utf16_unicodeScalars 264633 270555 +2.2% 0.98x (?)
CharIndexing_utf16_unicodeScalars_Backwards 291713 295224 +1.2% 0.99x (?)
CharIteration_ascii_unicodeScalars 145820 145539 -0.2% 1.00x (?)
CharIteration_ascii_unicodeScalars_Backwards 251721 248193 -1.4% 1.01x
CharIteration_chinese_unicodeScalars 110378 110346 -0.0% 1.00x (?)
CharIteration_chinese_unicodeScalars_Backwards 191074 187591 -1.8% 1.02x (?)
CharIteration_japanese_unicodeScalars 175252 174830 -0.2% 1.00x
CharIteration_japanese_unicodeScalars_Backwards 302028 298509 -1.2% 1.01x
CharIteration_korean_unicodeScalars 141325 141720 +0.3% 1.00x (?)
CharIteration_korean_unicodeScalars_Backwards 245336 240852 -1.8% 1.02x (?)
CharIteration_punctuatedJapanese_unicodeScalars 25852 26040 +0.7% 0.99x
CharIteration_punctuatedJapanese_unicodeScalars_Backwards 43883 43215 -1.5% 1.02x
CharIteration_punctuated_unicodeScalars 32586 32534 -0.2% 1.00x (?)
CharIteration_punctuated_unicodeScalars_Backwards 55784 54995 -1.4% 1.01x
CharIteration_russian_unicodeScalars 121653 121429 -0.2% 1.00x (?)
CharIteration_russian_unicodeScalars_Backwards 212574 207493 -2.4% 1.02x
CharIteration_tweet_unicodeScalars 288652 288074 -0.2% 1.00x (?)
CharIteration_tweet_unicodeScalars_Backwards 501409 492512 -1.8% 1.02x
CharIteration_utf16_unicodeScalars 125076 124876 -0.2% 1.00x (?)
CharIteration_utf16_unicodeScalars_Backwards 221541 217184 -2.0% 1.02x
CharacterLiteralsLarge 5705 5720 +0.3% 1.00x (?)
CharacterLiteralsSmall 659 659 +0.0% 1.00x
CharacterPropertiesFetch 5443 5510 +1.2% 0.99x (?)
CharacterPropertiesPrecomputed 4515 4374 -3.1% 1.03x (?)
CharacterPropertiesStashed 2293 2306 +0.6% 0.99x (?)
Chars 34767 34769 +0.0% 1.00x (?)
ClassArrayGetter 985 983 -0.2% 1.00x (?)
DataAccessBytes 2320 2319 -0.0% 1.00x (?)
DataAppendArray 5453 5517 +1.2% 0.99x (?)
DataAppendBytes 5183 5123 -1.2% 1.01x (?)
DataAppendDataLargeToLarge 67825 67001 -1.2% 1.01x (?)
DataAppendDataLargeToMedium 35116 34908 -0.6% 1.01x (?)
DataAppendDataLargeToSmall 33967 34131 +0.5% 1.00x (?)
DataAppendDataMediumToLarge 37116 37371 +0.7% 0.99x (?)
DataAppendDataMediumToMedium 6421 6750 +5.1% 0.95x (?)
DataAppendDataMediumToSmall 5776 5902 +2.2% 0.98x (?)
DataAppendDataSmallToLarge 36324 36808 +1.3% 0.99x (?)
DataAppendDataSmallToMedium 6040 5975 -1.1% 1.01x (?)
DataAppendSequence 1656870 1645417 -0.7% 1.01x
DataCopyBytes 2473 2488 +0.6% 0.99x (?)
DataCount 223 223 +0.0% 1.00x
DataMutateBytes 5145 5075 -1.4% 1.01x (?)
DataReplaceLarge 39932 38201 -4.3% 1.05x (?)
DataReplaceLargeBuffer 57396 56548 -1.5% 1.01x (?)
DataReplaceSmall 6729 6953 +3.3% 0.97x (?)
DataReset 2877 2912 +1.2% 0.99x (?)
DataSubscript 440 440 +0.0% 1.00x
DictOfArraysToArrayOfDicts 3303 3287 -0.5% 1.00x (?)
Dictionary 2298 2290 -0.3% 1.00x (?)
Dictionary2 2540 2578 +1.5% 0.99x
Dictionary2OfObjects 5845 5898 +0.9% 0.99x (?)
Dictionary3 1150 1166 +1.4% 0.99x
Dictionary3OfObjects 2248 2267 +0.8% 0.99x (?)
Dictionary4 1554 1534 -1.3% 1.01x (?)
Dictionary4OfObjects 2161 2113 -2.2% 1.02x (?)
DictionaryBridge 2089 2102 +0.6% 0.99x (?)
DictionaryCopy 299499 303192 +1.2% 0.99x
DictionaryFilter 302384 302248 -0.0% 1.00x (?)
DictionaryGroup 4076 4013 -1.5% 1.02x
DictionaryGroupOfObjects 7279 7198 -1.1% 1.01x (?)
DictionaryLiteral 8744 8725 -0.2% 1.00x (?)
DictionaryOfObjects 6123 5968 -2.5% 1.03x (?)
DictionaryRemove 17662 17783 +0.7% 0.99x
DictionaryRemoveOfObjects 54408 54549 +0.3% 1.00x (?)
DictionarySubscriptDefaultMutation 2029 2029 +0.0% 1.00x
DictionarySubscriptDefaultMutationArray 2269 2276 +0.3% 1.00x (?)
DictionarySubscriptDefaultMutationArrayOfObjects 9373 9413 +0.4% 1.00x (?)
DictionarySubscriptDefaultMutationOfObjects 5476 5447 -0.5% 1.01x (?)
DictionarySwap 5250 5249 -0.0% 1.00x (?)
DictionarySwapAt 35953 35913 -0.1% 1.00x (?)
DictionarySwapAtOfObjects 114704 114650 -0.0% 1.00x (?)
DictionarySwapOfObjects 19677 19487 -1.0% 1.01x (?)
DoubleWidthDivision 0 0 +0.0% 1.00x
DropFirstAnyCollection 12871 12675 -1.5% 1.02x
DropFirstAnyCollectionLazy 90853 89439 -1.6% 1.02x (?)
DropFirstAnySeqCRangeIter 19861 19757 -0.5% 1.01x
DropFirstAnySeqCRangeIterLazy 19856 19698 -0.8% 1.01x (?)
DropFirstAnySeqCntRange 12898 12870 -0.2% 1.00x (?)
DropFirstAnySeqCntRangeLazy 12758 12402 -2.8% 1.03x
DropFirstAnySequence 11311 11313 +0.0% 1.00x (?)
DropFirstAnySequenceLazy 11190 11198 +0.1% 1.00x (?)
DropFirstArray 3224 3135 -2.8% 1.03x
DropFirstArrayLazy 22267 21940 -1.5% 1.01x
DropFirstCountableRange 309 307 -0.6% 1.01x
DropFirstCountableRangeLazy 23955 23418 -2.2% 1.02x
DropFirstSequence 10643 10607 -0.3% 1.00x (?)
DropFirstSequenceLazy 10812 10622 -1.8% 1.02x
DropLastAnyCollection 4300 4247 -1.2% 1.01x
DropLastAnyCollectionLazy 30679 30421 -0.8% 1.01x (?)
DropLastAnySeqCRangeIter 36828 36743 -0.2% 1.00x (?)
DropLastAnySeqCRangeIterLazy 37658 37223 -1.2% 1.01x
DropLastAnySeqCntRange 4242 4289 +1.1% 0.99x (?)
DropLastAnySeqCntRangeLazy 4263 4172 -2.1% 1.02x
DropLastAnySequence 29141 29324 +0.6% 0.99x (?)
DropLastAnySequenceLazy 29434 29158 -0.9% 1.01x
DropLastCountableRange 106 106 +0.0% 1.00x
DropLastCountableRangeLazy 7987 7821 -2.1% 1.02x
DropLastSequence 29005 29130 +0.4% 1.00x (?)
DropLastSequenceLazy 28991 29224 +0.8% 0.99x
DropWhileAnyCollection 16547 16067 -2.9% 1.03x
DropWhileAnyCollectionLazy 18564 18017 -2.9% 1.03x
DropWhileAnySeqCRangeIter 21650 21510 -0.6% 1.01x
DropWhileAnySeqCRangeIterLazy 18446 18141 -1.7% 1.02x
DropWhileAnySeqCntRange 16340 16088 -1.5% 1.02x
DropWhileAnySeqCntRangeLazy 18252 18141 -0.6% 1.01x
DropWhileAnySequence 12880 12913 +0.3% 1.00x (?)
DropWhileAnySequenceLazy 10806 10820 +0.1% 1.00x (?)
DropWhileArrayLazy 13465 13539 +0.5% 0.99x
DropWhileCountableRange 3954 3969 +0.4% 1.00x (?)
DropWhileCountableRangeLazy 18176 17942 -1.3% 1.01x (?)
DropWhileSequence 12259 12238 -0.2% 1.00x (?)
DropWhileSequenceLazy 10584 10487 -0.9% 1.01x
EqualStringSubstring 70 70 +0.0% 1.00x
EqualSubstringString 70 70 +0.0% 1.00x
EqualSubstringSubstring 70 71 +1.4% 0.99x
EqualSubstringSubstringGenericEquatable 53 53 +0.0% 1.00x
ErrorHandling 6746 6458 -4.3% 1.04x (?)
ExclusivityGlobal 183 183 +0.0% 1.00x
ExclusivityIndependent 71 71 +0.0% 1.00x
FatCompactMap 296633 293457 -1.1% 1.01x (?)
FilterEvenUsingReduce 3537 3542 +0.1% 1.00x (?)
FilterEvenUsingReduceInto 1811 1814 +0.2% 1.00x (?)
FrequenciesUsingReduce 13097 13091 -0.0% 1.00x (?)
FrequenciesUsingReduceInto 5534 5671 +2.5% 0.98x (?)
Hanoi 19885 19879 -0.0% 1.00x (?)
HashTest 21697 21374 -1.5% 1.02x (?)
Histogram 6401 6384 -0.3% 1.00x (?)
Integrate 462 462 +0.0% 1.00x
IterateData 5465 5483 +0.3% 1.00x (?)
Join 1070 1071 +0.1% 1.00x (?)
LazilyFilteredArrayContains 733446 731256 -0.3% 1.00x (?)
LazilyFilteredArrays 1394486 1371214 -1.7% 1.02x
LazilyFilteredRange 452101 444243 -1.7% 1.02x
LessSubstringSubstring 71 71 +0.0% 1.00x
LessSubstringSubstringGenericComparable 54 54 +0.0% 1.00x
LinkedList 31993 32074 +0.3% 1.00x (?)
LuhnAlgoEager 5574 5742 +3.0% 0.97x (?)
LuhnAlgoLazy 5722 5729 +0.1% 1.00x (?)
MapReduce 25345 25382 +0.1% 1.00x (?)
MapReduceAnyCollection 25269 25436 +0.7% 0.99x
MapReduceAnyCollectionShort 35922 36086 +0.5% 1.00x (?)
MapReduceClass 29448 29395 -0.2% 1.00x (?)
MapReduceClassShort 40742 39825 -2.3% 1.02x (?)
MapReduceLazyCollection 22203 22355 +0.7% 0.99x (?)
MapReduceLazyCollectionShort 32366 32223 -0.4% 1.00x (?)
MapReduceLazySequence 18568 18721 +0.8% 0.99x
MapReduceSequence 28614 28659 +0.2% 1.00x (?)
MapReduceShort 36420 36203 -0.6% 1.01x (?)
MapReduceShortString 223 231 +3.6% 0.97x (?)
MapReduceString 1762 1734 -1.6% 1.02x
Memset 44117 44115 -0.0% 1.00x (?)
MonteCarloE 1150254 1155409 +0.4% 1.00x
MonteCarloPi 5239762 5221434 -0.3% 1.00x
NSDictionaryCastToSwift 6480 6465 -0.2% 1.00x (?)
NSError 710 741 +4.4% 0.96x (?)
NSStringConversion 435 435 +0.0% 1.00x
NibbleSort 439834 429609 -2.3% 1.02x
NopDeinit 190975 189783 -0.6% 1.01x (?)
ObjectAllocation 1254 1238 -1.3% 1.01x
ObjectiveCBridgeFromNSArrayAnyObject 26501 25761 -2.8% 1.03x (?)
ObjectiveCBridgeFromNSArrayAnyObjectForced 8637 8243 -4.6% 1.05x (?)
ObjectiveCBridgeFromNSArrayAnyObjectToString 44950 45258 +0.7% 0.99x (?)
ObjectiveCBridgeFromNSArrayAnyObjectToStringForced 44759 45629 +1.9% 0.98x (?)
ObjectiveCBridgeFromNSDictionaryAnyObject 105029 106102 +1.0% 0.99x (?)
ObjectiveCBridgeFromNSSetAnyObject 50514 51961 +2.9% 0.97x (?)
ObjectiveCBridgeFromNSSetAnyObjectForced 5333 5492 +3.0% 0.97x (?)
ObjectiveCBridgeFromNSSetAnyObjectToString 82154 85125 +3.6% 0.97x (?)
ObjectiveCBridgeFromNSString 2663 2642 -0.8% 1.01x (?)
ObjectiveCBridgeFromNSStringForced 2537 2550 +0.5% 0.99x (?)
ObjectiveCBridgeStubDataAppend 5443 5697 +4.7% 0.96x (?)
ObjectiveCBridgeStubDateMutation 717 744 +3.8% 0.96x
ObjectiveCBridgeStubFromArrayOfNSString 31484 31184 -1.0% 1.01x (?)
ObjectiveCBridgeStubFromNSDate 6776 6712 -0.9% 1.01x (?)
ObjectiveCBridgeStubFromNSString 991 983 -0.8% 1.01x
ObjectiveCBridgeStubFromNSStringRef 196 196 +0.0% 1.00x
ObjectiveCBridgeStubNSDataAppend 2921 2895 -0.9% 1.01x (?)
ObjectiveCBridgeStubToArrayOfNSString 28278 28331 +0.2% 1.00x (?)
ObjectiveCBridgeStubToNSDateRef 3475 3464 -0.3% 1.00x (?)
ObjectiveCBridgeStubToNSString 1571 1572 +0.1% 1.00x (?)
ObjectiveCBridgeStubToNSStringRef 153 153 +0.0% 1.00x
ObjectiveCBridgeStubURLAppendPathRef 359510 353750 -1.6% 1.02x (?)
ObjectiveCBridgeToNSArray 29051 29107 +0.2% 1.00x (?)
ObjectiveCBridgeToNSDictionary 43814 43409 -0.9% 1.01x (?)
ObjectiveCBridgeToNSSet 33812 33561 -0.7% 1.01x (?)
ObjectiveCBridgeToNSString 1354 1348 -0.4% 1.00x (?)
ObserverClosure 6360 6368 +0.1% 1.00x (?)
ObserverForwarderStruct 4308 4315 +0.2% 1.00x (?)
ObserverPartiallyAppliedMethod 7960 7914 -0.6% 1.01x (?)
ObserverUnappliedMethod 8172 8106 -0.8% 1.01x (?)
OpenClose 512 496 -3.1% 1.03x
PartialApplyDynamicType 39831 40058 +0.6% 0.99x (?)
Phonebook 17335 17308 -0.2% 1.00x (?)
PointerArithmetics 123156 123163 +0.0% 1.00x (?)
PolymorphicCalls 2343 2361 +0.8% 0.99x
PopFrontArray 4734 4677 -1.2% 1.01x
PopFrontArrayGeneric 5338 5348 +0.2% 1.00x (?)
PopFrontUnsafePointer 10352 10649 +2.9% 0.97x (?)
PrefixAnyCollection 12881 12689 -1.5% 1.02x
PrefixAnyCollectionLazy 88897 89623 +0.8% 0.99x (?)
PrefixAnySeqCRangeIter 16283 16275 -0.0% 1.00x (?)
PrefixAnySeqCRangeIterLazy 16320 16218 -0.6% 1.01x (?)
PrefixAnySeqCntRange 12841 12822 -0.1% 1.00x (?)
PrefixAnySeqCntRangeLazy 12723 12377 -2.7% 1.03x
PrefixAnySequence 9281 9331 +0.5% 0.99x (?)
PrefixAnySequenceLazy 9350 9333 -0.2% 1.00x (?)
PrefixArray 3230 3129 -3.1% 1.03x
PrefixArrayLazy 22093 21880 -1.0% 1.01x (?)
PrefixCountableRange 307 307 +0.0% 1.00x
PrefixCountableRangeLazy 23965 23513 -1.9% 1.02x (?)
PrefixSequence 8684 8697 +0.1% 1.00x (?)
PrefixSequenceLazy 8900 8741 -1.8% 1.02x
PrefixWhileAnyCollection 24011 23263 -3.1% 1.03x
PrefixWhileAnyCollectionLazy 15267 14933 -2.2% 1.02x
PrefixWhileAnySeqCRangeIter 31499 31552 +0.2% 1.00x (?)
PrefixWhileAnySeqCRangeIterLazy 15324 14970 -2.3% 1.02x
PrefixWhileAnySeqCntRange 23630 23256 -1.6% 1.02x
PrefixWhileAnySeqCntRangeLazy 15101 15024 -0.5% 1.01x (?)
PrefixWhileAnySequence 25576 25629 +0.2% 1.00x (?)
PrefixWhileAnySequenceLazy 9730 9755 +0.3% 1.00x (?)
PrefixWhileArray 10450 10246 -2.0% 1.02x
PrefixWhileArrayLazy 11762 11888 +1.1% 0.99x
PrefixWhileCountableRange 11158 11113 -0.4% 1.00x
PrefixWhileCountableRangeLazy 15232 14827 -2.7% 1.03x
PrefixWhileSequence 25067 25315 +1.0% 0.99x
PrefixWhileSequenceLazy 9399 9443 +0.5% 1.00x
Prims 9651 9757 +1.1% 0.99x (?)
PrimsSplit 9652 9658 +0.1% 1.00x (?)
QueueConcrete 14004 13958 -0.3% 1.00x (?)
QueueGeneric 18052 18118 +0.4% 1.00x (?)
RC4 16179 16178 -0.0% 1.00x (?)
RGBHistogram 24383 24455 +0.3% 1.00x (?)
RGBHistogramOfObjects 78421 75809 -3.3% 1.03x
RangeAssignment 2611 2704 +3.6% 0.97x
RangeIterationSigned 14764 14545 -1.5% 1.02x (?)
RangeIterationSigned64 35167 35446 +0.8% 0.99x (?)
RangeIterationUnsigned 32001 31994 -0.0% 1.00x (?)
RangeReplaceableCollectionPlusDefault 9866 10172 +3.1% 0.97x (?)
RecursiveOwnedParameter 5822 5816 -0.1% 1.00x (?)
RemoveWhereFilterInts 1930 1911 -1.0% 1.01x
RemoveWhereFilterString 1268 1281 +1.0% 0.99x
RemoveWhereFilterStrings 2431 2430 -0.0% 1.00x (?)
RemoveWhereMoveInts 3374 3360 -0.4% 1.00x
RemoveWhereMoveStrings 3887 3887 +0.0% 1.00x
RemoveWhereQuadraticInts 7591 7563 -0.4% 1.00x (?)
RemoveWhereQuadraticString 2222 2223 +0.0% 1.00x (?)
RemoveWhereQuadraticStrings 9225 9193 -0.3% 1.00x
RemoveWhereSwapInts 6058 6064 +0.1% 1.00x (?)
RemoveWhereSwapStrings 6753 6761 +0.1% 1.00x (?)
ReversedArray 12932 12661 -2.1% 1.02x
ReversedBidirectional 41652 41829 +0.4% 1.00x (?)
ReversedDictionary 22319 22273 -0.2% 1.00x (?)
RomanNumbers 1092269 1098721 +0.6% 0.99x (?)
SequenceAlgosAnySequence 10467 10207 -2.5% 1.03x
SequenceAlgosArray 739835 736313 -0.5% 1.00x
SequenceAlgosContiguousArray 277218 276403 -0.3% 1.00x
SequenceAlgosList 8210 8202 -0.1% 1.00x (?)
SequenceAlgosRange 1022782 1009627 -1.3% 1.01x
SequenceAlgosUnfoldSequence 5727 5728 +0.0% 1.00x (?)
SetExclusiveOr 17445 17443 -0.0% 1.00x (?)
SetExclusiveOr_OfObjects 45697 45587 -0.2% 1.00x (?)
SetIntersect 7251 7419 +2.3% 0.98x
SetIntersect_OfObjects 11235 11244 +0.1% 1.00x (?)
SetIsSubsetOf 1254 1268 +1.1% 0.99x
SetIsSubsetOf_OfObjects 1789 1772 -1.0% 1.01x (?)
SetUnion 12252 12371 +1.0% 0.99x (?)
SetUnion_OfObjects 32278 32080 -0.6% 1.01x (?)
SevenBoom 1657 1648 -0.5% 1.01x (?)
Sim2DArray 43444 43452 +0.0% 1.00x (?)
SortLargeExistentials 10987 10951 -0.3% 1.00x (?)
SortLettersInPlace 1817 1824 +0.4% 1.00x (?)
SortSortedStrings 928 919 -1.0% 1.01x
SortStrings 1859 1855 -0.2% 1.00x (?)
SortStringsUnicode 2651 2622 -1.1% 1.01x
StackPromo 95381 94272 -1.2% 1.01x (?)
StaticArray 2612 2637 +1.0% 0.99x (?)
StrComplexWalk 6208 6204 -0.1% 1.00x (?)
StrToInt 71686 71724 +0.1% 1.00x (?)
StringAdder 4659 4668 +0.2% 1.00x (?)
StringBuilder 6354 6311 -0.7% 1.01x (?)
StringBuilderLong 2771 2774 +0.1% 1.00x (?)
StringBuilderWithLongSubstring 4487 4658 +3.8% 0.96x (?)
StringComparison_abnormal 1313 1357 +3.4% 0.97x (?)
StringComparison_ascii 8609 8617 +0.1% 1.00x
StringComparison_emoji 1909 1909 +0.0% 1.00x
StringComparison_fastPrenormal 4653 4671 +0.4% 1.00x
StringComparison_latin1 3622 3655 +0.9% 0.99x
StringComparison_longSharedPrefix 2271 2267 -0.2% 1.00x (?)
StringComparison_nonBMPSlowestPrenormal 3532 3522 -0.3% 1.00x (?)
StringComparison_slowerPrenormal 3971 3967 -0.1% 1.00x (?)
StringComparison_zalgo 125544 125315 -0.2% 1.00x (?)
StringEdits 328372 344456 +4.9% 0.95x (?)
StringEnumRawValueInitialization 16566 16570 +0.0% 1.00x (?)
StringEqualPointerComparison 1518 1518 +0.0% 1.00x
StringFromLongWholeSubstring 22 22 +0.0% 1.00x
StringFromLongWholeSubstringGeneric 314 304 -3.2% 1.03x (?)
StringHasPrefixAscii 3104 3105 +0.0% 1.00x (?)
StringHasPrefixUnicode 113757 112253 -1.3% 1.01x (?)
StringHasSuffixAscii 3217 3217 +0.0% 1.00x
StringHasSuffixUnicode 105016 104746 -0.3% 1.00x (?)
StringInterpolation 13800 13933 +1.0% 0.99x (?)
StringInterpolationSmall 11908 11819 -0.7% 1.01x (?)
StringMatch 32386 32371 -0.0% 1.00x (?)
StringRemoveDupes 1370 1370 +0.0% 1.00x
StringUTF16Builder 7246 7272 +0.4% 1.00x (?)
StringUTF16SubstringBuilder 19694 20053 +1.8% 0.98x (?)
StringWalk 12315 12339 +0.2% 1.00x (?)
StringWithCString 37721 37690 -0.1% 1.00x (?)
StringWordBuilder 2373 2375 +0.1% 1.00x (?)
StringWordBuilderReservingCapacity 2064 2054 -0.5% 1.00x (?)
SubstringComparable 1555 1558 +0.2% 1.00x (?)
SubstringEqualString 1616 1608 -0.5% 1.00x (?)
SubstringEquatable 5177 5145 -0.6% 1.01x (?)
SubstringFromLongString 24 24 +0.0% 1.00x
SubstringFromLongStringGeneric 103 102 -1.0% 1.01x (?)
SuffixAnyCollection 4299 4232 -1.6% 1.02x
SuffixAnyCollectionLazy 29844 30035 +0.6% 0.99x (?)
SuffixAnySeqCRangeIter 32711 32476 -0.7% 1.01x (?)
SuffixAnySeqCRangeIterLazy 33186 33155 -0.1% 1.00x (?)
SuffixAnySeqCntRange 4252 4291 +0.9% 0.99x (?)
SuffixAnySeqCntRangeLazy 4266 4174 -2.2% 1.02x
SuffixAnySequence 24895 24874 -0.1% 1.00x (?)
SuffixAnySequenceLazy 25018 25005 -0.1% 1.00x (?)
SuffixCountableRange 105 105 +0.0% 1.00x
SuffixCountableRangeLazy 7990 7815 -2.2% 1.02x
SuffixSequence 24835 24791 -0.2% 1.00x
SuffixSequenceLazy 24849 24761 -0.4% 1.00x
SumUsingReduce 156930 156676 -0.2% 1.00x (?)
SumUsingReduceInto 149817 149921 +0.1% 1.00x (?)
SuperChars 110903 110195 -0.6% 1.01x (?)
TwoSum 3613 3657 +1.2% 0.99x
TypeFlood 192 194 +1.0% 0.99x (?)
UTF8Decode 28878 28918 +0.1% 1.00x
Walsh 12025 12006 -0.2% 1.00x (?)
WordCountHistogramASCII 35114 34733 -1.1% 1.01x
WordCountHistogramUTF16 41118 41138 +0.0% 1.00x (?)
WordCountUniqueASCII 7476 7370 -1.4% 1.01x
WordCountUniqueUTF16 11740 11650 -0.8% 1.01x (?)
WordSplitUTF16 25322 24535 -3.1% 1.03x (?)
XorLoop 23238 23240 +0.0% 1.00x (?)
Hardware Overview
  Model Name: Mac Pro
  Model Identifier: MacPro6,1
  Processor Name: 12-Core Intel Xeon E5
  Processor Speed: 2.7 GHz
  Number of Processors: 1
  Total Number of Cores: 12
  L2 Cache (per Core): 256 KB
  L3 Cache: 30 MB
  Memory: 64 GB

} else if sign == .minus {
return "-inf"
} else {
return "inf"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we short-circuit inf here, we probably don't need to worry about it at the next level down.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed infinity handling in the next layer down.

@@ -83,15 +83,29 @@ extension ${Self} : CustomStringConvertible {
/// A textual representation of the value.
@_inlineable // FIXME(sil-serialize-all)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can anyone explain why this is @_inlineable? This seems to me like a natural ABI boundary, so I'm curious if there was a specific reason for pushing it further down.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on the FIXME, Max added this mechanically, to smoothen the transition from previous versions where everything in the stdlib was implicitly inlinable. Attributes marked like this were added in bulk and they can (and should) be removed when we know better.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll do some perf testing to see if removing this makes a real difference.

let significand = value.significandBitPattern
if significand == 0 {
// Infinity
if value.isInfinite {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be omitted if inf is handled at the next layer out.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've removed infinity handling here. Infinity is now handled in two places: In the outermost Swift code for description and debugDescription (which return constant strings) and in the actual C formatting code. (Because of the former, the latter is not technically necessary except to ensure that the C formatter is actually complete.)

@@ -408,37 +408,17 @@ internal func _float${bits}ToString(
_ value: Float${bits}, debug: Bool
Copy link
Contributor Author

@tbkka tbkka Mar 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've kept the debug flag here even though it's not used. The only difference now between debugDescription and description is how they print NaNs. That difference is now entirely encapsulated -- description checks for and returns the static string immediately; the bottom C layer always produces the debug form, so debugDescription can just pass NaNs down.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should go ahead and get rid of the flag, but I'm OK with that happening in a follow-on cleanup patch.

let actualLength = _float${bits}ToStringImpl(bufferPtr, 32, value, debug)
return String._fromWellFormedCodeUnitSequence(
UTF8.self,
input: UnsafeBufferPointer(start: bufferPtr, count: Int(actualLength)))
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does anything need to change here to take advantage of @milseman's recent Small String work?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small string support hasn't been merged and I haven't come up with a clean alternative to _fromWellFormedCodeUnitSequence for them yet. When you merge, file a bug against me

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, I'd like to have something like String._unsafeFromWellFormedASCII(buffer:) to use here. If the buffer length is short, build and return a small ASCII string. Otherwise, allocate and memcpy to build a long ASCII string. In either case, omitting the charset shenanigans would be a sizable win.

Copy link
Member

@milseman milseman Mar 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -408,37 +408,17 @@ internal func _float${bits}ToString(
_ value: Float${bits}, debug: Bool
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should go ahead and get rid of the flag, but I'm OK with that happening in a follow-on cleanup patch.


#include "swift/Runtime/SwiftDtoa.h"

#if defined(__x86_64__) || defined(__aarch64__)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be #if defined __SIZEOF_INT128__, which will let it work on any platform where clang supports the type.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.


// Try to verify that the system floating-point types really are what we
// expect. Note that the code below is specific to these exact
// floating-point representations.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of these checks are assumptions baked into Swift/LLVM already. It's OK to have them for documentation purposes, but they're unnecessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are mostly intended as simple guards in case someone copies this code elsewhere. However, even within the Swift stdlib, we cannot safely assume that C long double really is Float80, so that check at least is important to have here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, that's fine.

#define multiply128xi32(lhs, rhs) (*(lhs) *= (rhs))
#define initialize128WithHigh64(dest, value) ((dest) = (__uint128_t)(value) << 64)
#define extractHigh64From128(arg) ((uint64_t)((arg) >> 64))
static int extractIntegerPart128(__uint128_t *fixed128, int fractionBits) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a short comment documenting the behavior of this function, as it doesn't just produce the integer part of fixed128, it also clears those bits in the source.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've split it into separate extract and clear operations to clarify.

__uint128_t full = (__uint128_t)lhs * rhs;
return (uint64_t)(full >> 32);
#else
static const uint64_t mask32 = ((uint64_t)1 << 32) - 1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would probably write this UINT32_MAX. I might also pull it out of these functions, since it's used over and over again.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've changed the spelling to UINT32_MAX. I'll see about consolidating it as part of a follow-on.

uint64_t t = (lhs & mask32) * (rhs & mask32);
t >>= 32;
uint64_t a = (lhs >> 32) * (rhs & mask32);
uint64_t b = (lhs & mask32) * (rhs >> 32);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The next bit can be simplified just a little if you want.

t += a + (b & mask32); // cannot overflow because a <= (2^64 - 2^33 + 1) and t,b <= (2^32 - 1).
t >>= 32;
t += (b >> 32);
return t + (lhs >> 32) * (rhs >> 32);

This is pretty minor, but it does save one add with carry. It's a bigger deal in the operations further down this file, where it saves multiple carries. More generally, you can clean all this up a lot with a few small helper functions (note that I've just sketched these pretty quickly here in the browser without testing):

static uint64_t mul32x32(uint32_t lhs, uint32_t rhs) {
    return (uint64_t)lhs*rhs;
}

static uint64_t mul32x32add1(uint32_t lhs, uint32_t rhs, uint32_t add) {
    return (uint64_t)lhs*rhs + add;
}

static uint64_t mul32x32add2(uint32_t lhs, uint32_t rhs, uint32_t add0, uint32_t add1) {
    return (uint64_t)lhs*rhs + add0 + add1;
}

static uint64_t multiply64x64RoundingDown(uint64_t lhs, uint64_t rhs) {
    uint64_t t00 = mul32x32(lhs, rhs);
    uint64_t t01 = mul32x32(lhs, rhs >> 32);
    uint64_t t10 = mul32x32add2(lhs >> 32, rhs, t00 >> 32, t01);
    return mul32x32add2(lhs >> 32, rhs >> 32, t01 >> 32, t10 >> 32);
}

static uint64_t multiply64x64RoundingUp(uint64_t lhs, uint64_t rhs) {
    uint64_t t00 = mul32x32add1(lhs, rhs, mask32);
    uint64_t t01 = mul32x32add1(lhs, rhs >> 32, mask32);
    uint64_t t10 = mul32x32add2(lhs >> 32, rhs, t00 >> 32, t01);
    return mul32x32add2(lhs >> 32, rhs >> 32, t01 >> 32, t10 >> 32);
}
....

I know that you've already run your tests on the existing 32b code, which is somewhat lengthy, so I'm OK with cleaning this up later as a minor optimization PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice ideas! I'll work through this in a follow-up PR.

#if !arch(i386)
// 32-bit i386 lacks signaling Double nans
expectNaN("snan", Double.signalingNaN)
expectNaN("-snan", -Double.signalingNaN)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rintaro : I'd like to add a test for Double(nan: 0x4000000000001, signaling: true), but I'm not sure how that should print. I think it should print as "snan(0x4000000000001)" but I think the previous code would print it as "snan" without the payload.

Copy link
Member

@rintaro rintaro Mar 27, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, Double.init(nan:signaling:) limits the max payload value to 0x3_ffff_ffff_ffff because bit50 is reserved for default payload for signaling NaN. And the Double.debugDescription for NaN takes up to bit49 into account. #2494

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can tell, the standard does not reserve any bit for signaling NaN. It only requires that the quiet bit is not set and the payload is not zero.

I would expect to reserve a single value as the default signaling payload (not a particular bit), so that Double(nan: 0x4_0000_0000_0000, signaling: true).debugDescription produces "snan" but Double(nan: 0x4_0000_0000_0001, signaling: true).debugDescription produces "snan(0x4000000000001)".

Copy link
Contributor

@stephentyrone stephentyrone Mar 27, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can tell, the standard does not reserve any bit for signaling NaN. It only requires that the quiet bit is not set and the payload is not zero.

It's weaker than that. There is no "quiet bit" (as a shall clause) in the standard. Some HW platforms use a "signaling bit" instead.

However, for platforms with the common-case behavior that the high-order significand bit is a quiet bit, Swift decided to canonicalize on b10xxx...xxx for qNaN and b01xxx...xxx for sNaN because this makes the same set of payloads encodable with each; otherwise quieting a sNaN is a lossy operation, which is undesirable.

(Note that we should actually switch to using b11xxx...xxx for qNaNs, so that b00xxx...xxx can serve as reserved bit patterns that are never generated by pure Swift operations on HW with the customary quiet bit. This is potentially useful for some boxing schemes.)

@stephentyrone
Copy link
Contributor

What significant outstanding issues block this proceeding at this point?

@tbkka
Copy link
Contributor Author

tbkka commented Mar 26, 2018

@swift-ci Please test and merge

@milseman
Copy link
Member

@swift-ci please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 116e0fe

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 116e0fe

@tbkka
Copy link
Contributor Author

tbkka commented Mar 27, 2018

@swift-ci Please smoke test

@milseman
Copy link
Member

milseman commented Mar 27, 2018

Looks like you need to update test/stdlib/PrintFloat.swift.gyb for nan printing on i386 simulator.

To iterate quicker, you can run ninja swift-stdlib-iphonesimulator-i386 from the build directory and then <path-to-llvm>/utils/lit/lit.py -sv <build-dir>/test-iphonesimulator-i386/stdlib/PrintFloat.swift.gyb.

(build-script with -i is also perfectly fine if that works for you)

20:13:57 stdout>>> check failed at /Users/buildnode/jenkins/workspace/swift-PR-osx/branch-master/swift/test/stdlib/PrintFloat.swift.gyb, line 636
20:13:57 stdout>>> stacktrace:
20:13:57 stdout>>>   #0: /Users/buildnode/jenkins/workspace/swift-PR-osx/branch-master/swift/test/stdlib/PrintFloat.swift.gyb:403
20:13:57 stdout>>> expected: "nan(0xffff)" (of type Swift.String)
20:13:57 stdout>>> actual: "nan" (of type Swift.String)
20:13:57 stdout>>> check failed at /Users/buildnode/jenkins/workspace/swift-PR-osx/branch-master/swift/test/stdlib/PrintFloat.swift.gyb, line 637
20:13:57 stdout>>> stacktrace:
20:13:57 stdout>>>   #0: /Users/buildnode/jenkins/workspace/swift-PR-osx/branch-master/swift/test/stdlib/PrintFloat.swift.gyb:403
20:13:57 stdout>>> expected: "nan(0x3ffffffffffff)" (of type Swift.String)
20:13:57 stdout>>> actual: "nan" (of type Swift.String)
20:13:57 stdout>>> check failed at /Users/buildnode/jenkins/workspace/swift-PR-osx/branch-master/swift/test/stdlib/PrintFloat.swift.gyb, line 638
20:13:57 stdout>>> stacktrace:
20:13:57 stdout>>>   #0: /Users/buildnode/jenkins/workspace/swift-PR-osx/branch-master/swift/test/stdlib/PrintFloat.swift.gyb:403
20:13:57 stdout>>> expected: "nan(0x3ffffffffffff)" (of type Swift.String)
20:13:57 stdout>>> actual: "nan" (of type Swift.String)
20:13:57 stdout>>> check failed at /Users/buildnode/jenkins/workspace/swift-PR-osx/branch-master/swift/test/stdlib/PrintFloat.swift.gyb, line 640
20:13:57 stdout>>> stacktrace:
20:13:57 stdout>>>   #0: /Users/buildnode/jenkins/workspace/swift-PR-osx/branch-master/swift/test/stdlib/PrintFloat.swift.gyb:403
20:13:57 stdout>>> expected: "-nan(0xffff)" (of type Swift.String)
20:13:57 stdout>>> actual: "-nan" (of type Swift.String)

edit: more details

@tbkka
Copy link
Contributor Author

tbkka commented Mar 29, 2018

@milseman: Thanks! It took a while to get the tests running, but I've verified the corrected results against the 32-bit i386 iPhone simulator. I'd like to verify it against a real 32-bit ARM device as well; any hints?

@tbkka
Copy link
Contributor Author

tbkka commented Mar 29, 2018

@swift-ci Please smoke test

@milseman
Copy link
Member

@jckarter any idea why there would be the following failure on Linux?

09:52:46 /home/buildnode/jenkins/workspace/swift-PR-Linux-smoke-test/branch-master/buildbot_linux/llvm-linux-x86_64/./bin/clang++   -DCMARK_STATIC_DEFINE -DGTEST_HAS_RTTI=0 -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -Istdlib/public/runtime -I/home/buildnode/jenkins/workspace/swift-PR-Linux-smoke-test/branch-master/swift/stdlib/public/runtime -Iinclude -I/home/buildnode/jenkins/workspace/swift-PR-Linux-smoke-test/branch-master/swift/include -I/home/buildnode/jenkins/workspace/swift-PR-Linux-smoke-test/branch-master/llvm/include -I/home/buildnode/jenkins/workspace/swift-PR-Linux-smoke-test/branch-master/buildbot_linux/llvm-linux-x86_64/include -I/home/buildnode/jenkins/workspace/swift-PR-Linux-smoke-test/branch-master/buildbot_linux/llvm-linux-x86_64/tools/clang/include -I/home/buildnode/jenkins/workspace/swift-PR-Linux-smoke-test/branch-master/llvm/tools/clang/include -I/home/buildnode/jenkins/workspace/swift-PR-Linux-smoke-test/branch-master/cmark/src -I/home/buildnode/jenkins/workspace/swift-PR-Linux-smoke-test/branch-master/buildbot_linux/cmark-linux-x86_64/src -isystem /usr/include/x86_64-linux-gnu -Wno-unknown-warning-option -Werror=unguarded-availability-new -fno-stack-protector -fPIC -fvisibility-inlines-hidden -Werror=date-time -Werror=unguarded-availability-new -std=c++11 -Wall -W -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers -Wcovered-switch-default -Wnon-virtual-dtor -Wdelete-non-virtual-dtor -Wstring-conversion -fcolor-diagnostics -ffunction-sections -fdata-sections -Werror=switch -Wdocumentation -Wimplicit-fallthrough -Wunreachable-code -Woverloaded-virtual -DOBJC_OLD_DISPATCH_PROTOTYPES=0 -fno-sanitize=all -DLLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING=1 -DSWIFT_RUNTIME_ENABLE_GUARANTEED_NORMAL_ARGUMENTS=1 -O3    -UNDEBUG  -Wall -Wglobal-constructors -Wexit-time-destructors -fvisibility=hidden -D__SWIFT_CURRENT_DYLIB=swiftCore -DswiftCore_EXPORTS -I/home/buildnode/jenkins/workspace/swift-PR-Linux-smoke-test/branch-master/swift/include -target x86_64-unknown-linux-gnu -O2 -g0 -DNDEBUG -MMD -MT stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/SwiftObject.mm.o -MF stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/SwiftObject.mm.o.d -o stdlib/public/runtime/CMakeFiles/swiftRuntime-linux-x86_64.dir/SwiftObject.mm.o -c /home/buildnode/jenkins/workspace/swift-PR-Linux-smoke-test/branch-master/swift/stdlib/public/runtime/SwiftObject.mm
09:52:46 In file included from /home/buildnode/jenkins/workspace/swift-PR-Linux-smoke-test/branch-master/swift/stdlib/public/runtime/SwiftObject.mm:29:
09:52:46 In file included from /home/buildnode/jenkins/workspace/swift-PR-Linux-smoke-test/branch-master/swift/include/swift/Runtime/Casting.h:20:
09:52:46 In file included from /home/buildnode/jenkins/workspace/swift-PR-Linux-smoke-test/branch-master/swift/include/swift/Runtime/Metadata.h:20:
09:52:46 
/usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/atomic:185:7: error: exception specification of explicitly defaulted default constructor does not match the calculated one
09:52:46       atomic() noexcept = default;
09:52:46       ^
09:52:46 /home/buildnode/jenkins/workspace/swift-PR-Linux-smoke-test/branch-master/swift/stdlib/public/runtime/WeakReference.h:151:36: note: in instantiation of template class 'std::atomic<swift::WeakReferenceBits>' requested here
09:52:46     std::atomic<WeakReferenceBits> nativeValue;
09:52:46                                    ^
09:52:46 1 error generated.

@jckarter
Copy link
Contributor

@milseman You may need to put noexcept on WeakReferenceBits' own default constructor. Maybe libstdc++ marks atomic() as noexcept but libc++ doesn't?

Adding a C source file somehow exposed an issue in an unrelated C++ file.
Thanks to Joe Groff for the fix.
@tbkka
Copy link
Contributor Author

tbkka commented Mar 30, 2018

Interesting: Adding any C file to stdlib/public/runtime/CMakeLists.txt will unmask this.

Some quick tests suggest that @jckarter's suggested change fixes it.

@tbkka
Copy link
Contributor Author

tbkka commented Mar 30, 2018

@swift-ci Please smoke test

@tbkka
Copy link
Contributor Author

tbkka commented Mar 30, 2018

Now the Linux build fails at a different point:

17:44:03 FAILED: tests/dispatch_starfish 
17:44:03 : && /home/buildnode/jenkins/workspace/swift-PR-Linux-smoke-test@2/branch-master/buildbot_linux/llvm-linux-x86_64/bin/clang  -O3 -DNDEBUG  -lrt tests/CMakeFiles/dispatch_starfish.dir/dispatch_starfish.c.o  -o tests/dispatch_starfish  src/libdispatch.so libBlocksRuntime.a -lbsd /home/buildnode/jenkins/workspace/swift-PR-Linux-smoke-test@2/branch-master/buildbot_linux/swift-linux-x86_64/lib/swift/linux/x86_64/libswiftCore.so /home/buildnode/jenkins/workspace/swift-PR-Linux-smoke-test@2/branch-master/buildbot_linux/swift-linux-x86_64/lib/swift/linux/x86_64/libswiftSwiftOnoneSupport.so tests/libbsdtests.a -pthread -Wl,-rpath,/home/buildnode/jenkins/workspace/swift-PR-Linux-smoke-test@2/branch-master/buildbot_linux/libdispatch-linux-x86_64/src:/home/buildnode/jenkins/workspace/swift-PR-Linux-smoke-test@2/branch-master/buildbot_linux/swift-linux-x86_64/lib/swift/linux/x86_64 && :
17:44:03 /home/buildnode/jenkins/workspace/swift-PR-Linux-smoke-test@2/branch-master/buildbot_linux/swift-linux-x86_64/lib/swift/linux/x86_64/libswiftCore.so: undefined reference to `__gnu_objc_personality_v0'
17:44:03 
clang-5.0: error: linker command failed with exit code 1 (use -v to see invocation)

Having a C file in stdlib/public/runtime causes strange
build failures on Linux in unrelated C++ files.

As a workaround, rename SwiftDtoa.c to .cpp to see
if that avoids the problems.
@tbkka
Copy link
Contributor Author

tbkka commented Mar 30, 2018

I've renamed SwiftDtoa.c to SwiftDtoa.cpp to see if that avoids the Linux problems.

@tbkka
Copy link
Contributor Author

tbkka commented Mar 30, 2018

@swift-ci Please smoke test

@gottesmm
Copy link
Contributor

@swift-ci smoke test

2 similar comments
@gottesmm
Copy link
Contributor

@swift-ci smoke test

@gottesmm
Copy link
Contributor

@swift-ci smoke test

@stephentyrone
Copy link
Contributor

@milseman @tbkka I would like to merge this and pursue the minor issues I raised in separate PRs. Any objections?

@tbkka
Copy link
Contributor Author

tbkka commented Apr 1, 2018

I've backed out 6cd5c20, since it's unrelated. (I think it's probably a good change, but should be handled separately.)

With that, as soon as the smoke tests look good, merge away!

@tbkka
Copy link
Contributor Author

tbkka commented Apr 1, 2018

@swift-ci smoke test

Copy link
Member

@milseman milseman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious

//
// Note: This is really a C file, but Swift's build system for Linux is
// partially allergic to C, so it's being compiled as ".cpp" for now. Please
// don't infect it with C++-isms.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Don't infect with C++-isms": Because I expect to have some discussions soon about using this code in other projects that may not be able to easily use C++. Keeping this pure C (at least for now) will simplify possible reuse.

Plus, my test suites are predominantly pure C right now and I have a number of simplifications and/or performance improvements to the code that I'm actively testing.

@milseman
Copy link
Member

milseman commented Apr 1, 2018

@swift-ci please smoke test

@stephentyrone stephentyrone merged commit 97a934c into swiftlang:master Apr 1, 2018
tbkka added a commit to tbkka/swift that referenced this pull request Apr 10, 2018
This was an oversight from PR swiftlang#15474.  Most of the Float80
tests were correctly compiled only on `!Windows && (x86 || i386)`
but I failed to mark some Float80 test data.

Fixes: Radar 39246292
@tbkka tbkka deleted the tbkka-floating-point-printing-C branch October 16, 2020 00:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

10 participants