This reduces memory use yet still provides the significant
performance gain seen when using a fast path for small integers.
Improvement of this CL comparing to code without fast path:
name old time/op new time/op delta
FormatIntSmall-8 35.6ns ± 1% 4.5ns ± 1% -87.30% (p=0.008 n=5+5)
AppendIntSmall-8 17.4ns ± 1% 9.4ns ± 3% -45.70% (p=0.008 n=5+5)
For comparison, here's the improvement before this CL to code without
fast path (1% better for FormatIntSmall):
name old time/op new time/op delta
FormatIntSmall-8 35.6ns ± 1% 4.0ns ± 3% -88.64% (p=0.008 n=5+5)
AppendIntSmall-8 17.4ns ± 1% 8.2ns ± 1% -52.80% (p=0.008 n=5+5)
Thus, the code in this CL performs slower for small integers using fast
path then the prior version, but this is relative to an already very fast
version:
name old time/op new time/op delta
FormatIntSmall-8 4.05ns ± 3% 4.52ns ± 1% +11.81% (p=0.008 n=5+5)
AppendIntSmall-8 8.21ns ± 1% 9.45ns ± 3% +15.05% (p=0.008 n=5+5)
Measured on 2.3 GHz Intel Core i7 running macOS Sierra 10.12.3.
Overall, it's still ~88% faster than without fast path for small integers,
so probably worth it as it removes 100 global string slices in favor of
a single string.
Credits: This is based on the original (but cleaned up) version of the
code by Aliaksandr Valialkin (https://go-review.googlesource.com/c/37963/).
Change-Id: Icda78679c8c14666d46257894e9fa3d7f35e58b8
Reviewed-on: https://go-review.googlesource.com/38319
Reviewed-by: Martin Möhrmann <moehrmann@google.com>
Some of the changes in CL golang.org/cl/38071/ assumed that / and %
could always be combined to use only one DIV instruction. However,
this is not the case for 64bit operands on a 32bit platform which use
seperate runtime functions to calculate division and modulo.
This CL restores the original optimizations that help on 32bit platforms
with negligible impact on 64bit platforms.
386:
name old time/op new time/op delta
FormatInt-2 6.06µs ± 0% 6.02µs ± 0% -0.70% (p=0.000 n=20+20)
AppendInt-2 4.98µs ± 0% 4.98µs ± 0% ~ (p=0.747 n=18+18)
FormatUint-2 1.93µs ± 0% 1.85µs ± 0% -4.19% (p=0.000 n=20+20)
AppendUint-2 1.71µs ± 0% 1.64µs ± 0% -3.68% (p=0.000 n=20+20)
amd64:
name old time/op new time/op delta
FormatInt-2 2.41µs ± 0% 2.41µs ± 0% -0.09% (p=0.010 n=18+18)
AppendInt-2 1.77µs ± 0% 1.77µs ± 0% +0.08% (p=0.000 n=18+18)
FormatUint-2 653ns ± 1% 653ns ± 0% ~ (p=0.178 n=20+20)
AppendUint-2 514ns ± 0% 513ns ± 0% -0.13% (p=0.000 n=20+17)
Change-Id: I574a18e54fb41b25fbe51ce696e7a8765abc79a6
Reviewed-on: https://go-review.googlesource.com/38051
Run-TryBot: Martin Möhrmann <moehrmann@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
The compiler recognizes that in a sequence q = x/y; r = x%y only
one division is required. Remove prior work-arounds and write
more readable straight-line code (this also results in fewer
instructions, though it doesn't appear to affect the benchmarks
significantly).
name old time/op new time/op delta
FormatInt-8 2.95µs ± 1% 2.92µs ± 5% ~ (p=0.952 n=5+5)
AppendInt-8 1.91µs ± 1% 1.89µs ± 2% ~ (p=0.421 n=5+5)
FormatUint-8 795ns ± 2% 782ns ± 4% ~ (p=0.444 n=5+5)
AppendUint-8 557ns ± 1% 557ns ± 2% ~ (p=0.548 n=5+5)
https://perf.golang.org/search?q=upload:20170310.1
Also:
- use uint instead of uintptr where we want to guarantee single-
register operations
- remove some unnecessary conversions (before indexing)
- add more comments and fix some comments
Change-Id: I04858dc2d798a6495879d9c7cfec2fdc2957b704
Reviewed-on: https://go-review.googlesource.com/38071
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Found by github.com/mvdan/unparam. Small performance win when the
utf8.RuneLen call is removed.
name old time/op new time/op delta
AppendQuoteRune-4 21.7ns ± 0% 21.4ns ± 0% -1.38% (p=0.008 n=5+5)
Change-Id: Ieb3b3e1148db7a3d854c81555a491edeff549f43
Reviewed-on: https://go-review.googlesource.com/37831
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
To match the language spec, strconv.Unquote needs to strip carriage
returns from the raw string.
Also fixes TestUnquote to not be a noop.
Fixes#15997
Change-Id: I2456f50f2ad3830f37e545f4f6774ced9fe609d7
Reviewed-on: https://go-review.googlesource.com/31210
Reviewed-by: Robert Griesemer <gri@golang.org>
The relevant benchmark (on an Intel i7-4510U machine):
name old time/op new time/op delta
FormatFloat/Slowpath64-4 68.6µs ± 0% 44.1µs ± 2% -35.71% (p=0.000 n=13+15)
Change-Id: I67eb0e81ce74ed57752d0280059f91419f09e93b
Reviewed-on: https://go-review.googlesource.com/30099
Reviewed-by: Robert Griesemer <gri@golang.org>
Changes beyond generated tables:
- Now supports aliases to handle deprecated
property classes.
- Some Mongolian letters are now modifiers.
Other changes:
- strconv: newly generated table to be in sync
- regexp/syntax: updated maxFold
Fixes#16191
Change-Id: I56bdf21ee2f775f2a82d0465b3772faf5c24cb61
Reviewed-on: https://go-review.googlesource.com/24496
Run-TryBot: Marcel van Lohuizen <mpvl@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This serves as an example of table-driven benchmarks which are analoguous to the common pattern for table-driven tests.
Change-Id: I47f94c121a7117dd1e4ba03b3f2f8bcb5da38063
Reviewed-on: https://go-review.googlesource.com/23470
Run-TryBot: Marcel van Lohuizen <mpvl@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
cmd and runtime were handled separately, and I'm intentionally skipped
syscall. This is the rest of the standard library.
CL generated mechanically with github.com/mdempsky/unconvert.
Change-Id: I9e0eff886974dedc37adb93f602064b83e469122
Reviewed-on: https://go-review.googlesource.com/22104
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
The tree's pretty inconsistent about single space vs double space
after a period in documentation. Make it consistently a single space,
per earlier decisions. This means contributors won't be confused by
misleading precedence.
This CL doesn't use go/doc to parse. It only addresses // comments.
It was generated with:
$ perl -i -npe 's,^(\s*// .+[a-z]\.) +([A-Z]),$1 $2,' $(git grep -l -E '^\s*//(.+\.) +([A-Z])')
$ go test go/doc -update
Change-Id: Iccdb99c37c797ef1f804a94b22ba5ee4b500c4f7
Reviewed-on: https://go-review.googlesource.com/20022
Reviewed-by: Rob Pike <r@golang.org>
Reviewed-by: Dave Day <djd@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This is a subset of https://golang.org/cl/20022 with only the copyright
header lines, so the next CL will be smaller and more reviewable.
Go policy has been single space after periods in comments for some time.
The copyright header template at:
https://golang.org/doc/contribute.html#copyright
also uses a single space.
Make them all consistent.
Change-Id: Icc26c6b8495c3820da6b171ca96a74701b4a01b0
Reviewed-on: https://go-review.googlesource.com/20111
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Named returned values should only be used on public funcs and methods
when it contributes to the documentation.
Named return values should not be used if they're only saving the
programmer a few lines of code inside the body of the function,
especially if that means there's stutter in the documentation or it
was only there so the programmer could use a naked return
statement. (Naked returns should not be used except in very small
functions)
This change is a manual audit & cleanup of public func signatures.
Signatures were not changed if:
* the func was private (wouldn't be in public godoc)
* the documentation referenced it
* the named return value was an interesting name. (i.e. it wasn't
simply stutter, repeating the name of the type)
There should be no changes in behavior. (At least: none intended)
Change-Id: I3472ef49619678fe786e5e0994bdf2d9de76d109
Reviewed-on: https://go-review.googlesource.com/20024
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Andrew Gerrand <adg@golang.org>
The current implementations of the AppendQuote functions use quoteWith
(through Quote) for quoting the given value and appends the returned
string to the dst byte slice. quoteWith internally creates a byte slice
on each call which gets converted to a string in Quote.
This means the AppendQuote functions always allocates a new byte slice
and a string only to append them to an existing byte slice. In the case
of (Append)QuoteRune the string passed to quoteWith will also needs to
be allocated from a rune first.
Split quoteWith into two functions (quoteWith and appendQuotedWith) and
replace the call to Quote inside AppendQuote with appendQuotedWith,
which appends directly to the byte slice passed to AppendQuote and also
avoids the []byte->string conversion.
Also introduce the 2 functions quoteRuneWith and appendQuotedRuneWith
that work the same way as quoteWith and appendQuotedWith, but take a
single rune instead of a string, to avoid allocating a new string when
appending a single rune, and use them in (Append)QuoteRune.
Also update the ToASCII and ToGraphic variants to use the new functions.
Benchmark results:
benchmark old ns/op new ns/op delta
BenchmarkQuote-8 428 503 +17.52%
BenchmarkQuoteRune-8 148 105 -29.05%
BenchmarkAppendQuote-8 435 307 -29.43%
BenchmarkAppendQuoteRune-8 158 23.5 -85.13%
benchmark old allocs new allocs delta
BenchmarkQuote-8 3 3 +0.00%
BenchmarkQuoteRune-8 3 2 -33.33%
BenchmarkAppendQuote-8 3 0 -100.00%
BenchmarkAppendQuoteRune-8 3 0 -100.00%
benchmark old bytes new bytes delta
BenchmarkQuote-8 144 144 +0.00%
BenchmarkQuoteRune-8 16 16 +0.00%
BenchmarkAppendQuote-8 144 0 -100.00%
BenchmarkAppendQuoteRune-8 16 0 -100.00%
Change-Id: I77c148d5c7242f1b0edbbeeea184878abb51a522
Reviewed-on: https://go-review.googlesource.com/18962
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This version of quoting allows runes in category Zs, such as the
ideographic space characters, to be passed through unquoted.
Still to do (maybe): A way to access this from Printf.
Updates #11511.
Change-Id: I3bae84b1aa0bc1b885318d3f67c5f451099a2a5a
Reviewed-on: https://go-review.googlesource.com/14184
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
Not sure if I'm on time for 1.5; Unicode 8 just got released.
Straighforward upgrade. Only changed maketables.go to prevent it from adding
the Cherokee upper and lower case mappings. This change causes the caseOrbit
table to NOT change. Added tests to verify that the relevant functions still
produce the correct result, even for Cherokee.
Fixes#11309
Change-Id: I42850f5b3399bde125b002efc78eff96dbd86a08
Reviewed-on: https://go-review.googlesource.com/11286
Reviewed-by: Russ Cox <rsc@golang.org>
Use optimized formatBits function to format mantissa and exponent.
Add benchmark for binary exponent float format.
on darwin/386
benchmark old ns/op new ns/op delta
BenchmarkAppendFloatBinaryExp 520 122 -76.54%
on darwin/amd64
benchmark old ns/op new ns/op delta
BenchmarkAppendFloatBinaryExp 76.9 84.3 +9.62%
Change-Id: If543552f1960e1655bed3a4130914e5eaa3aac69
Reviewed-on: https://go-review.googlesource.com/5600
Reviewed-by: Robert Griesemer <gri@golang.org>
Add compile time constants for bases 10 and 16 instead of computing the cutoff
value on every invocation of ParseUint by a division.
Reduce usage of slice operations.
amd64:
benchmark old ns/op new ns/op delta
BenchmarkAtoi 44.6 36.0 -19.28%
BenchmarkAtoiNeg 44.2 38.9 -11.99%
BenchmarkAtoi64 72.5 56.7 -21.79%
BenchmarkAtoi64Neg 66.1 58.6 -11.35%
386:
benchmark old ns/op new ns/op delta
BenchmarkAtoi 86.6 73.0 -15.70%
BenchmarkAtoiNeg 86.6 72.3 -16.51%
BenchmarkAtoi64 126 108 -14.29%
BenchmarkAtoi64Neg 126 108 -14.29%
Change-Id: I0a271132120d776c97bb4ed1099793c73e159893
Reviewed-on: https://go-review.googlesource.com/2460
Reviewed-by: Robert Griesemer <gri@golang.org>
Edge cases like base 2 and 36 conversions are now covered.
Many tests are mirrored from the itoa tests.
Added more test cases for syntax errors.
Change-Id: Iad8b2fb4854f898c2bfa18cdeb0cb4a758fcfc2e
Reviewed-on: https://go-review.googlesource.com/2463
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
Avoid the decimal lookup in digits array and compute the decimal character value directly.
Reduce calls to 64bit division on 32bit plattforms by splitting conversion into smaller blocks.
Convert value to uintptr type when it can be represented by uintptr.
on darwin/386
benchmark old ns/op new ns/op delta
BenchmarkFormatInt 8352 7466 -10.61%
BenchmarkAppendInt 4281 3401 -20.56%
BenchmarkFormatUint 2785 2251 -19.17%
BenchmarkAppendUint 1770 1223 -30.90%
on darwin/amd64
benchmark old ns/op new ns/op delta
BenchmarkFormatInt 5531 5492 -0.71%
BenchmarkAppendInt 2435 2295 -5.75%
BenchmarkFormatUint 1628 1569 -3.62%
BenchmarkAppendUint 726 750 +3.31%
Change-Id: Ifca281cbdd62ab7d7bd4b077a96da99eb12cf209
Reviewed-on: https://go-review.googlesource.com/2105
Reviewed-by: Robert Griesemer <gri@golang.org>
The new test case produces the longest string representation possible and thereby uses
all of the 65 bytes in the buffer array used by the formatBits function.
Change-Id: I11320c4de56ced5ff098b7e37f1be08e456573e2
Reviewed-on: https://go-review.googlesource.com/2108
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>