Commit graph

64 commits

Author SHA1 Message Date
erifan01
18a6fd44bb bytes, strings: moves indexRabinKarp function to internal/bytealg
In order to facilitate optimization of IndexAny and LastIndexAny, this patch moves
three Rabin-Karp related functions indexRabinKarp, hashStr and hashStrRev in strings
package to initernal/bytealg. There are also three functions in the bytes package with
the same names and functions but different parameter types. To highlight this, this
patch also moves them to internal/bytealg and gives them slightly different names.

Related benchmark changes on amd64 and arm64:

name          old time/op    new time/op    delta
pkg:strings goos:linux goarch:amd64
Index-16        14.0ns ± 1%    14.1ns ± 2%    ~     (p=0.738 n=5+5)
LastIndex-16    15.5ns ± 1%    15.7ns ± 4%    ~     (p=0.897 n=5+5)
pkg:bytes goos:linux goarch:amd64
Index/10-16     26.5ns ± 1%    26.5ns ± 0%    ~     (p=0.873 n=5+5)
Index/32-16     26.2ns ± 0%    25.7ns ± 0%  -1.68%  (p=0.008 n=5+5)
Index/4K-16     5.12µs ± 4%    5.14µs ± 2%    ~     (p=0.841 n=5+5)
Index/4M-16     5.44ms ± 3%    5.34ms ± 2%    ~     (p=0.056 n=5+5)
Index/64M-16    85.8ms ± 3%    84.6ms ± 0%  -1.37%  (p=0.016 n=5+5)

name          old speed      new speed      delta
pkg:bytes goos:linux goarch:amd64
Index/10-16    377MB/s ± 1%   377MB/s ± 0%    ~     (p=1.000 n=5+5)
Index/32-16   1.22GB/s ± 1%  1.24GB/s ± 0%  +1.66%  (p=0.008 n=5+5)
Index/4K-16    800MB/s ± 4%   797MB/s ± 2%    ~     (p=0.841 n=5+5)
Index/4M-16    771MB/s ± 3%   786MB/s ± 2%    ~     (p=0.056 n=5+5)
Index/64M-16   783MB/s ± 3%   793MB/s ± 0%  +1.36%  (p=0.016 n=5+5)

name         old time/op   new time/op   delta
pkg:strings goos:linux goarch:arm64
Index-8       22.6ns ± 0%   22.5ns ± 0%    ~     (p=0.167 n=5+5)
LastIndex-8   17.5ns ± 0%   17.5ns ± 0%    ~     (all equal)
pkg:bytes goos:linux goarch:arm64
Index/10-8    25.0ns ± 0%   25.0ns ± 0%    ~     (all equal)
Index/32-8     160ns ± 0%    160ns ± 0%    ~     (all equal)
Index/4K-8    6.26µs ± 0%   6.26µs ± 0%    ~     (p=0.167 n=5+5)
Index/4M-8    6.30ms ± 0%   6.31ms ± 0%    ~     (p=1.000 n=5+5)
Index/64M-8    101ms ± 0%    101ms ± 0%    ~     (p=0.690 n=5+5)

name         old speed     new speed     delta
pkg:bytes goos:linux goarch:arm64
Index/10-8   399MB/s ± 0%  400MB/s ± 0%  +0.08%  (p=0.008 n=5+5)
Index/32-8   200MB/s ± 0%  200MB/s ± 0%    ~     (p=0.127 n=4+5)
Index/4K-8   654MB/s ± 0%  654MB/s ± 0%  +0.01%  (p=0.016 n=5+5)
Index/4M-8   665MB/s ± 0%  665MB/s ± 0%    ~     (p=0.833 n=5+5)
Index/64M-8  665MB/s ± 0%  665MB/s ± 0%    ~     (p=0.913 n=5+5)

Change-Id: Icce3bc162bb8613ac36dc963a46c51f8e82ab842
Reviewed-on: https://go-review.googlesource.com/c/go/+/208638
Run-TryBot: eric fang <eric.fang@arm.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2020-03-04 17:36:05 +00:00
Thomas Symborski
a52db6403c strings: update Join parameter name for clarity
Change-Id: I83f806e76ef4d268b187bd273d78ceb41b7e8fa5
GitHub-Last-Rev: ee82eaae64
GitHub-Pull-Request: golang/go#36194
Reviewed-on: https://go-review.googlesource.com/c/go/+/211799
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2020-01-15 04:21:28 +00:00
po3rin
bf865823ba strings: fix nonexistent path in comment
There is a part in the comment that points to a non-existent file.
It seems to have been overlooked in following PR.
https://go-review.googlesource.com/c/go/+/98518/

Change-Id: I21dbfbd270c654d5cd7fa88d114a356862612d90
Reviewed-on: https://go-review.googlesource.com/c/go/+/210298
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2019-12-06 20:12:47 +00:00
Andrew Medvedev
78e5288b5c strings, bytes: clarify usage of EqualFolds
This clarifies meaning of "case folding" Unicode equality with more familiar "case insensitive" wording.
For case folding properties see ftp://ftp.unicode.org/Public/UNIDATA/CaseFolding.txt.

Fixes #33447

Change-Id: I6ee85ab398679bf2a0b7d18693985ff0979d6c5a
GitHub-Last-Rev: accc915933
GitHub-Pull-Request: golang/go#34434
Reviewed-on: https://go-review.googlesource.com/c/go/+/196717
Reviewed-by: Rob Pike <r@golang.org>
2019-09-21 21:45:58 +00:00
Andrew Todd
fbb819ebc4 strings: clarify usage of Title and ToTitle
This is intended to help clear up confusion around the usage of the
Title and ToTitle functions. It includes a link to define title case
to distinguish it from upper case. It also includes an additional
example for the ToTitle function to showcase the difference in behavior
between it and the Title function.

Fixes #33302

Change-Id: I44e62962fb04d0d22966a39eda3a2d16de7a2291
Reviewed-on: https://go-review.googlesource.com/c/go/+/187825
Reviewed-by: Rob Pike <r@golang.org>
2019-07-30 02:52:57 +00:00
Martin Möhrmann
3259bc4419 strings, bytes: add ToValidUTF8
The newly added functions create a copy of their input with all bytes in
invalid UTF-8 byte sequences mapped to the UTF-8 byte sequence
given as replacement parameter.

Fixes #25805

Change-Id: Iaf65f65b40c0581c6bb000f1590408d6628321d0
Reviewed-on: https://go-review.googlesource.com/c/go/+/142003
Run-TryBot: Martin Möhrmann <moehrmann@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2019-05-01 18:31:47 +00:00
Максадбек Ахмедов
a01d108e30 strings: remove "a copy of the string" from ToUpper/ToLower comments
When string letters are all in lower/upper cases, both functions respectively
return original string.

Fixes #30987

Change-Id: Ie8d664f7af5e087f82c1bc156933e9a995645bf4
Reviewed-on: https://go-review.googlesource.com/c/go/+/171735
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2019-04-14 16:19:31 +00:00
Tobias Klauser
78175474c4 strings: use Go style character range comparison in ToUpper/ToLower
As noted by Brad in CL 170954 for package bytes.

Change-Id: I2772a356299e54ba5b7884d537e6649039adb9be
Reviewed-on: https://go-review.googlesource.com/c/go/+/171198
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2019-04-09 13:57:16 +00:00
Tobias Klauser
f70d457a36 strings: unindent Fields
CL 56470 unindented bytes.Fields, but not strings.Fields. Do so now to
make it easier to diff the two functions for potential differences.

Change-Id: Ifef81f50cee64e8277e91efa5ec5521d8d21d3bd
Reviewed-on: https://go-review.googlesource.com/c/go/+/170951
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2019-04-08 08:18:38 +00:00
Ben Hoyt
4b4f222a0d bytes, strings: speed up TrimSpace 4-5x for common ASCII cases
This change adds a fast path for ASCII strings to both
strings.TrimSpace and bytes.TrimSpace. It doesn't slow down the
non-ASCII path much, if at all.

I added benchmarks for strings.TrimSpace as it didn't have any, and
I fleshed out the benchmarks for bytes.TrimSpace as it just had one
case (for ASCII). The benchmarks (and the code!) are now the same
between the two versions. Below are the benchmark results:

strings.TrimSpace:

name                      old time/op  new time/op  delta
TrimSpace/NoTrim-8        18.6ns ± 0%   3.8ns ± 0%  -79.53%  (p=0.000 n=5+4)
TrimSpace/ASCII-8         33.5ns ± 2%   6.0ns ± 3%  -82.05%  (p=0.008 n=5+5)
TrimSpace/SomeNonASCII-8  97.1ns ± 1%  88.6ns ± 1%   -8.68%  (p=0.008 n=5+5)
TrimSpace/JustNonASCII-8   144ns ± 0%   143ns ± 0%     ~     (p=0.079 n=4+5)

bytes.TrimSpace:

name                      old time/op  new time/op  delta
TrimSpace/NoTrim-8        18.9ns ± 1%   4.1ns ± 1%  -78.34%  (p=0.008 n=5+5)
TrimSpace/ASCII-8         29.9ns ± 0%   6.3ns ± 1%  -79.06%  (p=0.008 n=5+5)
TrimSpace/SomeNonASCII-8  91.5ns ± 0%  82.3ns ± 0%  -10.03%  (p=0.008 n=5+5)
TrimSpace/JustNonASCII-8   150ns ± 0%   150ns ± 0%     ~     (all equal)

Fixes #29122

Change-Id: Ica45cd86a219cadf60173ec9db260133cd1d7951
Reviewed-on: https://go-review.googlesource.com/c/go/+/152917
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2019-03-12 15:52:17 +00:00
Keith Randall
ad4a58e315 strings,bytes: use inlineable function trampolines instead of linkname
Cleans things up quite a bit.

There's still a few more, like runtime.cmpstring, which might also
be worth fixing.

Change-Id: Ide18dd621efc129cc686db223f47fa0b044b5580
Reviewed-on: https://go-review.googlesource.com/c/148578
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
2018-11-08 20:52:47 +00:00
沈涛
d0a91f2305 strings: remove empty line
Change-Id: Ibdca4f7002585b00d7f69d710285a8e0f69c598a
GitHub-Last-Rev: eb8f800c98
GitHub-Pull-Request: golang/go#28659
Reviewed-on: https://go-review.googlesource.com/c/148477
Reviewed-by: Russ Cox <rsc@golang.org>
2018-11-08 16:17:53 +00:00
Martin Möhrmann
f74de24fbd strings: correctly handle invalid utf8 sequences in Map
When an invalid UTF-8 byte sequence is decoded in a range loop over a string
a utf8.RuneError rune is returned. This is not distinguishable from decoding
the valid '\uFFFD' sequence representing utf8.RuneError from a string without
further checks within the range loop.

The previous Map code did not do any extra checks and would thereby not map
invalid UTF-8 byte sequences correctly when those were mapping to utf8.RuneError.

Fix this by adding the extra checks necessary to distinguish the decoding
of invalid utf8 byte sequences from decoding the sequence for utf8.RuneError
when the mapping of a rune is utf8.RuneError.

This fix does not result in a measureable performance regression:
name                old time/op  new time/op  delta
ByteByteMap         1.05µs ± 3%  1.03µs ± 3%   ~     (p=0.118 n=10+10)
Map/identity/ASCII   169ns ± 2%   170ns ± 1%   ~     (p=0.501 n=9+10)
Map/identity/Greek   298ns ± 1%   303ns ± 4%   ~     (p=0.338 n=10+10)
Map/change/ASCII     323ns ± 3%   325ns ± 4%   ~     (p=0.679 n=8+10)
Map/change/Greek     628ns ± 5%   635ns ± 1%   ~     (p=0.460 n=10+9)
MapNoChanges         120ns ± 4%   119ns ± 1%   ~     (p=0.496 n=10+9)

Fixes #26305

Change-Id: I70e99fa244983c5040756fa4549ac1e8cb6022c3
Reviewed-on: https://go-review.googlesource.com/c/131495
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-10-03 21:27:10 +00:00
Brad Fitzpatrick
ebdc0b8d68 bytes, strings: add ReplaceAll
Credit to Harald Nordgren for the proposal in
https://golang.org/cl/137456 and #27864.

Fixes #27864

Change-Id: I80546683b0623124fe4627a71af88add2f6c1c27
Reviewed-on: https://go-review.googlesource.com/137855
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2018-09-26 20:51:23 +00:00
Tom Thorogood
14e7f174c1 strings: use Builder in ToUpper and ToLower
Map was optimized to use Builder in 45c7d80832, which avoided the []byte
to string converstion. This left the ToUpper and ToLower ASCII fast path
with an extra allocation over Map.

name                                        old time/op    new time/op    delta
ToUpper/#00-12                                3.59ns ± 4%    3.71ns ± 1%     ~     (p=0.056 n=5+5)
ToUpper/ONLYUPPER-12                          11.8ns ± 2%    10.5ns ± 2%  -10.85%  (p=0.008 n=5+5)
ToUpper/abc-12                                31.8ns ± 1%    25.3ns ± 1%  -20.40%  (p=0.008 n=5+5)
ToUpper/AbC123-12                             46.2ns ± 7%    31.9ns ± 8%  -30.89%  (p=0.008 n=5+5)
ToUpper/azAZ09_-12                            47.1ns ± 8%    32.6ns ± 4%  -30.77%  (p=0.008 n=5+5)
ToUpper/longStrinGwitHmixofsmaLLandcAps-12     137ns ±15%     104ns ±11%  -24.11%  (p=0.008 n=5+5)
ToUpper/longɐstringɐwithɐnonasciiⱯchars-12     231ns ± 1%     228ns ± 1%     ~     (p=0.079 n=5+5)
ToUpper/ɐɐɐɐɐ-12                               207ns ± 3%     206ns ± 1%     ~     (p=0.913 n=5+5)
ToUpper/a\u0080\U0010ffff-12                  90.8ns ± 1%    89.6ns ± 1%   -1.30%  (p=0.024 n=5+5)
ToLower/#00-12                                3.59ns ± 1%    4.26ns ± 2%  +18.66%  (p=0.008 n=5+5)
ToLower/abc-12                                6.32ns ± 1%    6.62ns ± 1%   +4.72%  (p=0.008 n=5+5)
ToLower/AbC123-12                             45.0ns ±13%    31.5ns ± 4%  -29.89%  (p=0.008 n=5+5)
ToLower/azAZ09_-12                            48.8ns ± 6%    33.2ns ± 3%  -31.91%  (p=0.008 n=5+5)
ToLower/longStrinGwitHmixofsmaLLandcAps-12     149ns ±13%      98ns ± 8%  -34.30%  (p=0.008 n=5+5)
ToLower/LONGⱯSTRINGⱯWITHⱯNONASCIIⱯCHARS-12     237ns ± 4%     237ns ± 2%     ~     (p=0.635 n=5+5)
ToLower/ⱭⱭⱭⱭⱭ-12                               181ns ± 1%     181ns ± 1%     ~     (p=0.762 n=5+5)
ToLower/A\u0080\U0010ffff-12                  90.6ns ± 1%    92.5ns ± 1%   +2.05%  (p=0.016 n=5+5)

name                                        old alloc/op   new alloc/op   delta
ToUpper/#00-12                                 0.00B          0.00B          ~     (all equal)
ToUpper/ONLYUPPER-12                           0.00B          0.00B          ~     (all equal)
ToUpper/abc-12                                 6.00B ± 0%     3.00B ± 0%  -50.00%  (p=0.008 n=5+5)
ToUpper/AbC123-12                              16.0B ± 0%      8.0B ± 0%  -50.00%  (p=0.008 n=5+5)
ToUpper/azAZ09_-12                             16.0B ± 0%      8.0B ± 0%  -50.00%  (p=0.008 n=5+5)
ToUpper/longStrinGwitHmixofsmaLLandcAps-12     64.0B ± 0%     32.0B ± 0%  -50.00%  (p=0.008 n=5+5)
ToUpper/longɐstringɐwithɐnonasciiⱯchars-12     48.0B ± 0%     48.0B ± 0%     ~     (all equal)
ToUpper/ɐɐɐɐɐ-12                               48.0B ± 0%     48.0B ± 0%     ~     (all equal)
ToUpper/a\u0080\U0010ffff-12                   16.0B ± 0%     16.0B ± 0%     ~     (all equal)
ToLower/#00-12                                 0.00B          0.00B          ~     (all equal)
ToLower/abc-12                                 0.00B          0.00B          ~     (all equal)
ToLower/AbC123-12                              16.0B ± 0%      8.0B ± 0%  -50.00%  (p=0.008 n=5+5)
ToLower/azAZ09_-12                             16.0B ± 0%      8.0B ± 0%  -50.00%  (p=0.008 n=5+5)
ToLower/longStrinGwitHmixofsmaLLandcAps-12     64.0B ± 0%     32.0B ± 0%  -50.00%  (p=0.008 n=5+5)
ToLower/LONGⱯSTRINGⱯWITHⱯNONASCIIⱯCHARS-12     48.0B ± 0%     48.0B ± 0%     ~     (all equal)
ToLower/ⱭⱭⱭⱭⱭ-12                               32.0B ± 0%     32.0B ± 0%     ~     (all equal)
ToLower/A\u0080\U0010ffff-12                   16.0B ± 0%     16.0B ± 0%     ~     (all equal)

name                                        old allocs/op  new allocs/op  delta
ToUpper/#00-12                                  0.00           0.00          ~     (all equal)
ToUpper/ONLYUPPER-12                            0.00           0.00          ~     (all equal)
ToUpper/abc-12                                  2.00 ± 0%      1.00 ± 0%  -50.00%  (p=0.008 n=5+5)
ToUpper/AbC123-12                               2.00 ± 0%      1.00 ± 0%  -50.00%  (p=0.008 n=5+5)
ToUpper/azAZ09_-12                              2.00 ± 0%      1.00 ± 0%  -50.00%  (p=0.008 n=5+5)
ToUpper/longStrinGwitHmixofsmaLLandcAps-12      2.00 ± 0%      1.00 ± 0%  -50.00%  (p=0.008 n=5+5)
ToUpper/longɐstringɐwithɐnonasciiⱯchars-12      1.00 ± 0%      1.00 ± 0%     ~     (all equal)
ToUpper/ɐɐɐɐɐ-12                                2.00 ± 0%      2.00 ± 0%     ~     (all equal)
ToUpper/a\u0080\U0010ffff-12                    1.00 ± 0%      1.00 ± 0%     ~     (all equal)
ToLower/#00-12                                  0.00           0.00          ~     (all equal)
ToLower/abc-12                                  0.00           0.00          ~     (all equal)
ToLower/AbC123-12                               2.00 ± 0%      1.00 ± 0%  -50.00%  (p=0.008 n=5+5)
ToLower/azAZ09_-12                              2.00 ± 0%      1.00 ± 0%  -50.00%  (p=0.008 n=5+5)
ToLower/longStrinGwitHmixofsmaLLandcAps-12      2.00 ± 0%      1.00 ± 0%  -50.00%  (p=0.008 n=5+5)
ToLower/LONGⱯSTRINGⱯWITHⱯNONASCIIⱯCHARS-12      1.00 ± 0%      1.00 ± 0%     ~     (all equal)
ToLower/ⱭⱭⱭⱭⱭ-12                                1.00 ± 0%      1.00 ± 0%     ~     (all equal)
ToLower/A\u0080\U0010ffff-12                    1.00 ± 0%      1.00 ± 0%     ~     (all equal)

Updates #26304

Change-Id: I4179e21d5e60d950b925fe3ffc74b376b82812d2
GitHub-Last-Rev: 2c7c3bb75b
GitHub-Pull-Request: golang/go#27872
Reviewed-on: https://go-review.googlesource.com/137575
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-09-26 14:41:52 +00:00
erifan01
691f5c34ad strings, bytes: optimize function Index
This change compares the first two characters instead of the first one,
and if they match, the entire string is compared. Comparing the first two
characters helps to filter out the case where the first character matches
but the subsequent characters do not match, thereby improving the substring
search speed in this case.

Benchmarks with no effect or minimal impact (less than 5%) is not listed,
the following are improved benchmarks:
On arm64:
strings:
IndexPeriodic/IndexPeriodic16-8   172890.00ns +- 2%   124156.20ns +- 0%  -28.19%  (p=0.008 n=5+5)
IndexPeriodic/IndexPeriodic32-8    78092.80ns +- 0%    65138.60ns +- 0%  -16.59%  (p=0.008 n=5+5)
IndexPeriodic/IndexPeriodic64-8    42322.20ns +- 0%    34661.60ns +- 0%  -18.10%  (p=0.008 n=5+5)
bytes:
IndexPeriodic/IndexPeriodic16-8     183468.20ns +- 6%     123759.00ns +- 0%  -32.54%  (p=0.008 n=5+5)
IndexPeriodic/IndexPeriodic32-8      84776.40ns +- 0%      63907.80ns +- 0%  -24.62%  (p=0.008 n=5+5)
IndexPeriodic/IndexPeriodic64-8      45835.60ns +- 0%      34194.20ns +- 0%  -25.40%  (p=0.008 n=5+5)

On amd64:
strings:
IndexPeriodic/IndexPeriodic8-16    219499.00ns +- 0%   178123.40ns +- 0%  -18.85%  (p=0.008 n=5+5)
IndexPeriodic/IndexPeriodic16-16   109760.20ns +- 0%    88957.80ns +- 0%  -18.95%  (p=0.008 n=5+5)
IndexPeriodic/IndexPeriodic32-16    54943.00ns +- 0%    44573.80ns +- 0%  -18.87%  (p=0.008 n=5+5)
IndexPeriodic/IndexPeriodic64-16    29804.80ns +- 0%    24417.80ns +- 0%  -18.07%  (p=0.008 n=5+5)
bytes:
IndexPeriodic/IndexPeriodic8-16     226592.60ns +- 0%    181183.20ns +- 0%  -20.04%  (p=0.008 n=5+5)
IndexPeriodic/IndexPeriodic16-16    111432.60ns +- 0%     90634.60ns +- 0%  -18.66%  (p=0.008 n=5+5)
IndexPeriodic/IndexPeriodic32-16     55640.60ns +- 0%     45433.00ns +- 0%  -18.35%  (p=0.008 n=5+5)
IndexPeriodic/IndexPeriodic64-16     30833.00ns +- 0%     24784.20ns +- 0%  -19.62%  (p=0.008 n=5+5)

Change-Id: I2d9e7e138d29e960d20a203eb74dc2ec976a9d71
Reviewed-on: https://go-review.googlesource.com/131177
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
2018-09-13 16:21:55 +00:00
Phil Pearl
317afdc3fb strings: simplify Join using Builder
The existing implementation has a bunch of special cases and
suffers an additional allocation for longer arrays. We can replace
this code with a simple implementation using Builder, improve
performance and reduce complexity.

name      old time/op    new time/op    delta
Join/0-8    3.53ns ± 3%    3.72ns ± 2%   +5.56%  (p=0.000 n=10+10)
Join/1-8    3.94ns ± 4%    3.40ns ± 4%  -13.57%  (p=0.000 n=10+10)
Join/2-8    57.0ns ± 3%    51.0ns ± 1%  -10.48%  (p=0.000 n=10+9)
Join/3-8    74.9ns ± 2%    65.5ns ± 4%  -12.60%  (p=0.000 n=10+10)
Join/4-8     105ns ± 0%      79ns ± 4%  -24.63%  (p=0.000 n=6+10)
Join/5-8     116ns ± 2%      91ns ± 4%  -21.95%  (p=0.000 n=10+10)
Join/6-8     131ns ± 1%     104ns ± 1%  -20.66%  (p=0.000 n=10+10)
Join/7-8     141ns ± 0%     114ns ± 4%  -18.82%  (p=0.000 n=9+10)

name      old alloc/op   new alloc/op   delta
Join/0-8     0.00B          0.00B          ~     (all equal)
Join/1-8     0.00B          0.00B          ~     (all equal)
Join/2-8     16.0B ± 0%     16.0B ± 0%     ~     (all equal)
Join/3-8     32.0B ± 0%     32.0B ± 0%     ~     (all equal)
Join/4-8     96.0B ± 0%     48.0B ± 0%  -50.00%  (p=0.000 n=10+10)
Join/5-8     96.0B ± 0%     48.0B ± 0%  -50.00%  (p=0.000 n=10+10)
Join/6-8      128B ± 0%       64B ± 0%  -50.00%  (p=0.000 n=10+10)
Join/7-8      128B ± 0%       64B ± 0%  -50.00%  (p=0.000 n=10+10)

name      old allocs/op  new allocs/op  delta
Join/0-8      0.00           0.00          ~     (all equal)
Join/1-8      0.00           0.00          ~     (all equal)
Join/2-8      1.00 ± 0%      1.00 ± 0%     ~     (all equal)
Join/3-8      1.00 ± 0%      1.00 ± 0%     ~     (all equal)
Join/4-8      2.00 ± 0%      1.00 ± 0%  -50.00%  (p=0.000 n=10+10)
Join/5-8      2.00 ± 0%      1.00 ± 0%  -50.00%  (p=0.000 n=10+10)
Join/6-8      2.00 ± 0%      1.00 ± 0%  -50.00%  (p=0.000 n=10+10)
Join/7-8      2.00 ± 0%      1.00 ± 0%  -50.00%  (p=0.000 n=10+10)

Change-Id: I866a50e809c398512cb87648c955eaa4bf4d8606
Reviewed-on: https://go-review.googlesource.com/132895
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-09-02 20:08:07 +00:00
go101
7a178df0bc strings: use Builder in Repeat to avoid an allocation
name           old time/op    new time/op    delta
Repeat/5x1-4     95.9ns ± 2%    70.1ns ± 2%  -26.93%  (p=0.000 n=9+10)
Repeat/5x2-4      146ns ± 3%     100ns ± 2%  -31.99%  (p=0.000 n=10+10)
Repeat/5x6-4      203ns ± 3%     140ns ± 4%  -30.77%  (p=0.000 n=10+10)
Repeat/10x1-4     139ns ± 3%      92ns ± 4%  -34.08%  (p=0.000 n=10+10)
Repeat/10x2-4     188ns ± 4%     122ns ± 2%  -35.34%  (p=0.000 n=10+10)
Repeat/10x6-4     264ns ± 5%     179ns ± 4%  -32.15%  (p=0.000 n=10+10)

name           old alloc/op   new alloc/op   delta
Repeat/5x1-4      10.0B ± 0%      5.0B ± 0%  -50.00%  (p=0.000 n=10+10)
Repeat/5x2-4      32.0B ± 0%     16.0B ± 0%  -50.00%  (p=0.000 n=10+10)
Repeat/5x6-4      64.0B ± 0%     32.0B ± 0%  -50.00%  (p=0.000 n=10+10)
Repeat/10x1-4     32.0B ± 0%     16.0B ± 0%  -50.00%  (p=0.000 n=10+10)
Repeat/10x2-4     64.0B ± 0%     32.0B ± 0%  -50.00%  (p=0.000 n=10+10)
Repeat/10x6-4      128B ± 0%       64B ± 0%  -50.00%  (p=0.000 n=10+10)

Change-Id: I6619336da636df39c560f6cc481519f48c6e8176
GitHub-Last-Rev: 4b2c73f3bf
GitHub-Pull-Request: golang/go#25894
Reviewed-on: https://go-review.googlesource.com/118855
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-08-22 16:40:21 +00:00
Johan Brandhorst
841a9136b3 strings, bytes: avoid unnecessary function literals
A number of explicit function literals found through the
unlambda linter are removed.

Fixes #26802

Change-Id: I0b122bdd95e9cb804c77efe20483fdf681c8154e
Reviewed-on: https://go-review.googlesource.com/127756
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
2018-08-22 16:09:06 +00:00
Michael Fraenkel
45c7d80832 strings: use Builder in Map
Use a builder to avoid the copy when converting the []byte to a string.

name                  old time/op    new time/op    delta
ByteByteMap-8            796ns ± 5%     700ns ± 1%  -12.00%  (p=0.000 n=9+8)
Map/identity/ASCII-8     123ns ± 8%     126ns ± 7%     ~     (p=0.194 n=10+10)
Map/identity/Greek-8     198ns ± 2%     204ns ± 5%   +2.99%  (p=0.008 n=9+10)
Map/change/ASCII-8       266ns ±10%     202ns ± 3%  -24.19%  (p=0.000 n=10+10)
Map/change/Greek-8       450ns ± 4%     406ns ± 1%   -9.73%  (p=0.000 n=9+10)
MapNoChanges-8          85.4ns ± 3%    90.2ns ±11%   +5.67%  (p=0.000 n=9+10)

name                  old alloc/op   new alloc/op   delta
ByteByteMap-8             416B ± 0%      208B ± 0%  -50.00%  (p=0.000 n=10+10)
Map/identity/ASCII-8     0.00B          0.00B          ~     (all equal)
Map/identity/Greek-8     0.00B          0.00B          ~     (all equal)
Map/change/ASCII-8        128B ± 0%       64B ± 0%  -50.00%  (p=0.000 n=10+10)
Map/change/Greek-8        160B ± 0%       80B ± 0%  -50.00%  (p=0.000 n=10+10)
MapNoChanges-8           0.00B          0.00B          ~     (all equal)

name                  old allocs/op  new allocs/op  delta
ByteByteMap-8             2.00 ± 0%      1.00 ± 0%  -50.00%  (p=0.000 n=10+10)
Map/identity/ASCII-8      0.00           0.00          ~     (all equal)
Map/identity/Greek-8      0.00           0.00          ~     (all equal)
Map/change/ASCII-8        2.00 ± 0%      1.00 ± 0%  -50.00%  (p=0.000 n=10+10)
Map/change/Greek-8        2.00 ± 0%      1.00 ± 0%  -50.00%  (p=0.000 n=10+10)
MapNoChanges-8            0.00           0.00          ~     (all equal)

Fixes #26304

Change-Id: Ideec9dfc29b0b8107f34fc634247081d0031777d
Reviewed-on: https://go-review.googlesource.com/122875
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-08-22 00:53:54 +00:00
Kevin Zita
8272484840 strings: revise ToUpperSpecial and ToLowerSpecial wording
Fixes #26654

Change-Id: I4832c45cad40607b83e1a8a9b562fa12e639b7d9
GitHub-Last-Rev: c9ceedb7d4
GitHub-Pull-Request: golang/go#26781
Reviewed-on: https://go-review.googlesource.com/127716
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-08-21 04:38:58 +00:00
Daniel Martí
62d270e0a4 strings: add note for new Go developers to TrimLeft and TrimRight
If one quickly looks at the strings package godoc, reading the name
TrimLeft, one might think it removes a prefix from the string.

The function's godoc does explain its purpose, but it's apparent that it
is not clear enough, as there have been numerous raised issues about
this confusion: #12771 #14657 #18160 #19371 #20085 #25328 #26119. These
questions are also frequent elsewhere on the internet.

Add a very short paragraph to the godoc, to hopefully point new Go
developers in the right direction faster. Do the same thing for
TrimRight and TrimSuffix.

Change-Id: I4dee5ed8dd9fba565b4755bad12ae1ee6d277959
Reviewed-on: https://go-review.googlesource.com/121637
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-06-29 16:57:32 +00:00
Martin Möhrmann
8c62fc0ca3 strings: fix encoding of \u0080 in map
Fix encoding of PAD (U+0080) which has the same value as utf8.RuneSelf
being incorrectly encoded as \x80 in strings.Map due to using <= instead
of a < comparison operator to check one byte encodings for utf8.

Fixes #25242

Change-Id: Ib6c7d1f425a7ba81e431b6d64009e713d94ea3bc
Reviewed-on: https://go-review.googlesource.com/111286
Run-TryBot: Martin Möhrmann <moehrmann@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-05-04 05:37:45 +00:00
Eric Pauley
9d11c63b64 bytes, strings: improve EqualFold fast version for ASCII
The existing implementation only considers the special ASCII
case when the lower character is an upper case letter. This
means that most ASCII comparisons use unicode.SimpleFold even
when it is not necessary.

benchmark                old ns/op     new ns/op     delta
BenchmarkEqualFold-8     450           390           -13.33%

Change-Id: I735ca3c30fc0145c186d2a54f31fd39caab2c3fa
Reviewed-on: https://go-review.googlesource.com/110018
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-05-01 18:52:19 +00:00
Keith Randall
ee58eccc56 internal/bytealg: move short string Index implementations into bytealg
Also move the arm64 CountByte implementation while we're here.

Fixes #19792

Change-Id: I1e0fdf1e03e3135af84150a2703b58dad1b0d57e
Reviewed-on: https://go-review.googlesource.com/98518
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-03-04 19:49:44 +00:00
Keith Randall
45964e4f9c internal/bytealg: move Count to bytealg
Move bytes.Count and strings.Count to bytealg.

Update #19792

Change-Id: I3e4e14b504a0b71758885bb131e5656e342cf8cb
Reviewed-on: https://go-review.googlesource.com/98495
Run-TryBot: Keith Randall <khr@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2018-03-04 17:49:25 +00:00
Russ Cox
2a166c93a3 bytes, strings: restore O(1) behavior of IndexAny(s, "") and LastIndexAny(s, "")
CL 65851 (bytes) and CL 65910 (strings) “improve[d] readability”
by removing the special case that bypassed the whole function body
when chars == "". In doing so, yes, the function was unindented a
level, which is nice, but the runtime of that case went from O(1) to O(n)
where n = len(s).

I don't know if anyone's code depends on the O(1) behavior in this case,
but quite possibly someone's does.

This CL adds the special case back, with a comment to prevent future
deletions, and without reindenting each function body in full.

Change-Id: I5aba33922b304dd1b8657e6d51d6c937a7f95c81
Reviewed-on: https://go-review.googlesource.com/78112
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-11-15 21:26:05 +00:00
Keith Randall
a025277505 bytes,strings: in generic Index, use mix of IndexByte and Rabin-Karp
Use IndexByte first, as it allows us to skip lots of bytes quickly.
If IndexByte is generating a lot of false positives, switch over to Rabin-Karp.

Experiments for ppc64le
bytes:
name                             old time/op  new time/op  delta
IndexPeriodic/IndexPeriodic2-2   1.12ms ± 0%  0.18ms ± 0%  -83.54%  (p=0.000 n=10+9)
IndexPeriodic/IndexPeriodic4-2    635µs ± 0%   184µs ± 0%  -71.06%  (p=0.000 n=9+9)
IndexPeriodic/IndexPeriodic8-2    289µs ± 0%   184µs ± 0%  -36.51%  (p=0.000 n=10+9)
IndexPeriodic/IndexPeriodic16-2   133µs ± 0%   183µs ± 0%  +37.68%  (p=0.000 n=10+9)
IndexPeriodic/IndexPeriodic32-2  68.3µs ± 0%  70.2µs ± 0%   +2.76%  (p=0.000 n=10+10)
IndexPeriodic/IndexPeriodic64-2  35.8µs ± 0%  36.6µs ± 0%   +2.17%  (p=0.000 n=8+10)

strings:
name                             old time/op  new time/op  delta
IndexPeriodic/IndexPeriodic2-2    184µs ± 0%   184µs ± 0%   +0.11%  (p=0.029 n=4+4)
IndexPeriodic/IndexPeriodic4-2    184µs ± 0%   184µs ± 0%     ~     (p=0.886 n=4+4)
IndexPeriodic/IndexPeriodic8-2    184µs ± 0%   184µs ± 0%     ~     (p=0.486 n=4+4)
IndexPeriodic/IndexPeriodic16-2   185µs ± 1%   184µs ± 0%     ~     (p=0.343 n=4+4)
IndexPeriodic/IndexPeriodic32-2   184µs ± 0%    69µs ± 0%  -62.37%  (p=0.029 n=4+4)
IndexPeriodic/IndexPeriodic64-2   184µs ± 0%    37µs ± 0%  -80.17%  (p=0.029 n=4+4)

Fixes #22578

Change-Id: If2a4d8554cb96bfd699b58149d13ac294615f8b8
Reviewed-on: https://go-review.googlesource.com/76070
Reviewed-by: Alberto Donizetti <alb.donizetti@gmail.com>
2017-11-15 17:35:09 +00:00
Agniva De Sarker
65fbf0e834 strings: optimize ToLower
Handling the ASCII case inline and call unicode.ToLower only
for non-ASCII cases.

Gives good improvements for the ASCII case and minor perf
degrade for non-ASCII case

name                                     old time/op    new time/op    delta
ToLower/#00                                10.8ns ± 1%     9.0ns ± 1%  -16.83%  (p=0.008 n=5+5)
ToLower/abc                                23.3ns ± 4%    12.6ns ± 1%  -46.01%  (p=0.008 n=5+5)
ToLower/AbC123                             91.0ns ± 2%    70.4ns ± 0%  -22.59%  (p=0.008 n=5+5)
ToLower/azAZ09_                             104ns ± 3%      75ns ± 1%  -28.35%  (p=0.008 n=5+5)
ToLower/longStrinGwitHmixofsmaLLandcAps     254ns ± 4%     157ns ± 0%  -38.19%  (p=0.016 n=5+4)
ToLower/LONGⱯSTRINGⱯWITHⱯNONASCIIⱯCHARS     446ns ± 1%     451ns ± 1%     ~     (p=0.056 n=5+5)
ToLower/ⱭⱭⱭⱭⱭ                               345ns ± 1%     348ns ± 0%   +0.93%  (p=0.016 n=5+5)

name                                     old alloc/op   new alloc/op   delta
ToLower/#00                                 0.00B          0.00B          ~     (all equal)
ToLower/abc                                 0.00B          0.00B          ~     (all equal)
ToLower/AbC123                              16.0B ± 0%     16.0B ± 0%     ~     (all equal)
ToLower/azAZ09_                             24.0B ± 0%     16.0B ± 0%  -33.33%  (p=0.008 n=5+5)
ToLower/longStrinGwitHmixofsmaLLandcAps     80.0B ± 0%     64.0B ± 0%  -20.00%  (p=0.008 n=5+5)
ToLower/LONGⱯSTRINGⱯWITHⱯNONASCIIⱯCHARS     96.0B ± 0%     96.0B ± 0%     ~     (all equal)
ToLower/ⱭⱭⱭⱭⱭ                               48.0B ± 0%     48.0B ± 0%     ~     (all equal)

Ran on a machine with Intel(R) Core(TM) i5-5200U CPU @ 2.20GHz

Fixes #17859

Change-Id: Iacc1e6b77e1aedba9447a6e94352606f131ea597
Reviewed-on: https://go-review.googlesource.com/76470
Reviewed-by: Marvin Stenger <marvin.stenger94@gmail.com>
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
2017-11-08 21:47:19 +00:00
Agniva De Sarker
13cfb15cb1 strings: optimize ToUpper
Handling the ASCII case inline and call unicode.ToUpper only
for non-ascii cases.

Gives good improvements for the ascii case and minor perf
degrade for non-ascii case

name                                     old time/op    new time/op    delta
ToUpper/#00                                11.7ns ± 8%     8.0ns ± 1%  -31.95%  (p=0.008 n=5+5)
ToUpper/ONLYUPPER                          45.6ns ± 5%    19.9ns ± 1%  -56.40%  (p=0.008 n=5+5)
ToUpper/abc                                77.4ns ± 1%    57.0ns ± 1%  -26.32%  (p=0.008 n=5+5)
ToUpper/AbC123                             92.1ns ± 4%    67.7ns ± 2%  -26.57%  (p=0.008 n=5+5)
ToUpper/azAZ09_                             105ns ± 6%      67ns ± 2%  -36.26%  (p=0.000 n=5+4)
ToUpper/longStrinGwitHmixofsmaLLandcAps     255ns ± 1%     140ns ± 1%  -45.01%  (p=0.029 n=4+4)
ToUpper/longɐstringɐwithɐnonasciiⱯchars     440ns ± 1%     447ns ± 0%   +1.49%  (p=0.016 n=5+4)
ToUpper/ɐɐɐɐɐ                               370ns ± 4%     366ns ± 1%     ~     (p=0.667 n=5+5)

name                                     old alloc/op   new alloc/op   delta
ToUpper/#00                                 0.00B          0.00B          ~     (all equal)
ToUpper/ONLYUPPER                           0.00B          0.00B          ~     (all equal)
ToUpper/abc                                 16.0B ± 0%      6.0B ± 0%  -62.50%  (p=0.008 n=5+5)
ToUpper/AbC123                              16.0B ± 0%     16.0B ± 0%     ~     (all equal)
ToUpper/azAZ09_                             24.0B ± 0%     16.0B ± 0%  -33.33%  (p=0.008 n=5+5)
ToUpper/longStrinGwitHmixofsmaLLandcAps     80.0B ± 0%     64.0B ± 0%  -20.00%  (p=0.008 n=5+5)
ToUpper/longɐstringɐwithɐnonasciiⱯchars     96.0B ± 0%     96.0B ± 0%     ~     (all equal)
ToUpper/ɐɐɐɐɐ                               64.0B ± 0%     64.0B ± 0%     ~     (all equal)

Ran on a machine with Intel(R) Core(TM) i5-5200U CPU @ 2.20GHz

Updates #17859

Change-Id: I0735ac4a4a36e8a8f6cc06f2c16b871f12b4abf9
Reviewed-on: https://go-review.googlesource.com/68370
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-11-07 18:44:50 +00:00
Gabriel Aszalos
c82ee79247 strings: improve readability of IndexAny and LastIndexAny functions.
This change removes the check of len(chars) > 0 inside the Index and
IndexAny functions which was redundant.

Change-Id: Iffbc0f2b3332c6e31c7514b5f644b6fe7bdcfe0d
Reviewed-on: https://go-review.googlesource.com/65910
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
2017-09-25 18:23:11 +00:00
Martin Möhrmann
d180d18666 strings: use slice instead of list and array in Fields comment
Change-Id: I70b839ff0ae5f015587390a82616ebb1d657d71a
Reviewed-on: https://go-review.googlesource.com/55490
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
Run-TryBot: Martin Möhrmann <moehrmann@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-08-14 21:25:53 +00:00
Martin Möhrmann
fee7f2ab16 strings: speed up FieldsFunc
Increases performance of FieldsFunc by recording the start and end
of the fields in an array. The first 32 fields are saved in a pre-allocated
array on the stack. This avoids the old behavior of iterating over the
input string two times but uses more allocations when more than 32 fields
are encountered.

Additionally code for handling non-ASCII containing strings from Fields is
removed and replaced by a call to the new faster FieldsFunc function.

Overall this still leads to a slowdown for Fields on non-ASCII strings
while speeding up Fields in general.

name                      old time/op    new time/op     delta
Fields/ASCII/16              116ns ± 5%      115ns ± 5%       ~     (p=0.480 n=10+10)
Fields/ASCII/256             765ns ± 1%      761ns ± 2%       ~     (p=0.171 n=10+10)
Fields/ASCII/4096           12.5µs ± 1%     12.7µs ± 1%     +1.82%  (p=0.000 n=10+10)
Fields/ASCII/65536           226µs ± 1%      226µs ± 2%       ~     (p=0.739 n=10+10)
Fields/ASCII/1048576        5.12ms ± 1%     5.12ms ± 1%       ~     (p=0.696 n=8+10)
Fields/Mixed/16              172ns ± 1%      233ns ± 1%    +35.90%  (p=0.000 n=9+10)
Fields/Mixed/256            1.18µs ± 2%     2.45µs ± 1%   +107.47%  (p=0.000 n=10+10)
Fields/Mixed/4096           20.3µs ± 1%     43.1µs ± 2%   +112.41%  (p=0.000 n=10+10)
Fields/Mixed/65536           364µs ± 1%      704µs ± 1%    +93.56%  (p=0.000 n=9+10)
Fields/Mixed/1048576        7.07ms ± 2%    13.34ms ± 4%    +88.83%  (p=0.000 n=10+10)
FieldsFunc/ASCII/16          274ns ± 1%      188ns ± 3%    -31.44%  (p=0.000 n=10+10)
FieldsFunc/ASCII/256        3.69µs ± 1%     2.06µs ± 2%    -44.26%  (p=0.000 n=10+10)
FieldsFunc/ASCII/4096       59.9µs ± 1%     35.3µs ± 2%    -41.10%  (p=0.000 n=10+10)
FieldsFunc/ASCII/65536       958µs ± 1%      567µs ± 1%    -40.82%  (p=0.000 n=10+9)
FieldsFunc/ASCII/1048576    16.3ms ± 2%     11.0ms ± 3%    -32.52%  (p=0.000 n=10+10)
FieldsFunc/Mixed/16          309ns ± 1%      213ns ± 0%    -30.98%  (p=0.000 n=10+6)
FieldsFunc/Mixed/256        3.83µs ± 1%     2.14µs ± 1%    -44.01%  (p=0.000 n=10+10)
FieldsFunc/Mixed/4096       66.2µs ± 2%     37.8µs ± 1%    -42.85%  (p=0.000 n=10+10)
FieldsFunc/Mixed/65536      1.09ms ± 1%     0.63ms ± 1%    -42.73%  (p=0.000 n=10+10)
FieldsFunc/Mixed/1048576    18.6ms ± 3%     12.0ms ± 2%    -35.50%  (p=0.000 n=10+10)

Fixes #17856
Fixes #19789

Change-Id: I9f5a560e534566fd81963651f342c8f44cfb0469
Reviewed-on: https://go-review.googlesource.com/42810
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
2017-08-13 09:58:01 +00:00
Kevin Burke
e93eb2843c strings: avoid unnecessary variable setting
We initialize fieldStart to 0, then set it to i without ever reading
0, so we might as well just initialize it to i.

Change-Id: I17905b25d54a62b6bc76f915353756ed5eb6972b
Reviewed-on: https://go-review.googlesource.com/52933
Reviewed-by: Martin Möhrmann <moehrmann@google.com>
Reviewed-by: Avelino <t@avelino.xxx>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-08-09 04:19:17 +00:00
Alberto Donizetti
3a27f28e9b strings: document Split{,N,After,AfterN} edge cases
Apparently people get confused by the fact that

  Split("", ",")

returns []{""} instead of []{}.

This is actually just a consequence of the fact that if the separator
sep (2nd argument) is not found the string s (1st argument), then the
Split* functions return a length 1 slice with the string s in it.

Document the general case: if sep is not in s, what you get is a len 1
slice with s in it; unless both s and sep are "", in that case you get
an empty slice of length 0.

Fixes #19726

Change-Id: I64c8220b91acd1e5aa1cc1829199e0cd8c47c404
Reviewed-on: https://go-review.googlesource.com/44950
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
2017-06-06 15:48:54 +00:00
Michael Darakananda
a5083bbf07 strings: simplify indexFunc
A for-range loop is simpler and also generally faster nowadays:

TrimASCII/1:1-4      69.2ns ± 1%  72.3ns ± 4%  +4.55%  (p=0.001 n=8+8)
TrimASCII/1:2-4       114ns ± 4%   104ns ± 3%  -8.71%  (p=0.000 n=9+8)
TrimASCII/1:4-4       112ns ± 1%   109ns ± 2%  -2.57%  (p=0.000 n=8+9)
TrimASCII/1:8-4       120ns ± 2%   118ns ± 4%    ~     (p=0.097 n=9+9)
TrimASCII/1:16-4      137ns ± 3%   132ns ± 3%  -3.82%  (p=0.001 n=9+9)
TrimASCII/16:1-4      129ns ± 1%   125ns ± 2%  -3.38%  (p=0.000 n=8+9)
TrimASCII/16:2-4      167ns ± 3%   159ns ± 1%  -4.99%  (p=0.000 n=9+8)
TrimASCII/16:4-4      165ns ± 2%   162ns ± 1%  -1.91%  (p=0.005 n=8+9)
TrimASCII/16:8-4      173ns ± 2%   170ns ± 1%  -1.29%  (p=0.018 n=9+9)
TrimASCII/16:16-4     188ns ± 2%   186ns ± 2%  -1.13%  (p=0.022 n=8+9)
TrimASCII/256:1-4    1.06µs ± 1%  0.98µs ± 2%  -7.64%  (p=0.000 n=8+9)
TrimASCII/256:2-4    1.08µs ± 1%  1.06µs ± 2%  -1.95%  (p=0.006 n=9+9)
TrimASCII/256:4-4    1.09µs ± 1%  1.07µs ± 3%    ~     (p=0.059 n=9+9)
TrimASCII/256:8-4    1.10µs ± 1%  1.07µs ± 2%  -2.63%  (p=0.000 n=9+8)
TrimASCII/256:16-4   1.10µs ± 1%  1.08µs ± 1%  -1.90%  (p=0.000 n=8+9)
TrimASCII/4096:1-4   15.8µs ± 1%  14.5µs ± 1%  -8.59%  (p=0.000 n=9+9)
TrimASCII/4096:2-4   15.6µs ± 1%  15.4µs ± 2%  -1.27%  (p=0.021 n=8+8)
TrimASCII/4096:4-4   15.6µs ± 1%  15.4µs ± 2%    ~     (p=0.094 n=9+9)
TrimASCII/4096:8-4   15.7µs ± 1%  15.8µs ± 6%    ~     (p=0.555 n=8+8)
TrimASCII/4096:16-4  15.7µs ± 2%  15.3µs ± 1%  -2.64%  (p=0.000 n=8+9)

Change-Id: I9b06689b67c0cf2c7ff446fc63a8c44cc5d6a246
Reviewed-on: https://go-review.googlesource.com/32891
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-05-24 03:16:44 +00:00
Josselin Costanzi
d206af1e6c strings: optimize Count for amd64
Move optimized Count implementation from bytes to runtime. Use in
both bytes and strings packages.
Add CountByte benchmark to strings.

Strings benchmarks:
name                       old time/op    new time/op    delta
CountHard1-4                 226µs ± 1%      226µs ± 2%      ~     (p=0.247 n=10+10)
CountHard2-4                 316µs ± 1%      315µs ± 0%      ~     (p=0.133 n=9+10)
CountHard3-4                 919µs ± 1%      920µs ± 1%      ~     (p=0.968 n=10+9)
CountTorture-4              15.4µs ± 1%     15.7µs ± 1%    +2.47%  (p=0.000 n=10+9)
CountTortureOverlapping-4   9.60ms ± 0%     9.65ms ± 1%      ~     (p=0.247 n=10+10)
CountByte/10-4              26.3ns ± 1%     10.9ns ± 1%   -58.71%  (p=0.000 n=9+9)
CountByte/32-4              42.7ns ± 0%     14.2ns ± 0%   -66.64%  (p=0.000 n=10+10)
CountByte/4096-4            3.07µs ± 0%     0.31µs ± 2%   -89.99%  (p=0.000 n=9+10)
CountByte/4194304-4         3.48ms ± 1%     0.34ms ± 1%   -90.09%  (p=0.000 n=10+9)
CountByte/67108864-4        55.6ms ± 1%      7.0ms ± 0%   -87.49%  (p=0.000 n=9+8)

name                      old speed      new speed       delta
CountByte/10-4             380MB/s ± 1%    919MB/s ± 1%  +142.21%  (p=0.000 n=9+9)
CountByte/32-4             750MB/s ± 0%   2247MB/s ± 0%  +199.62%  (p=0.000 n=10+10)
CountByte/4096-4          1.33GB/s ± 0%  13.32GB/s ± 2%  +898.13%  (p=0.000 n=9+10)
CountByte/4194304-4       1.21GB/s ± 1%  12.17GB/s ± 1%  +908.87%  (p=0.000 n=10+9)
CountByte/67108864-4      1.21GB/s ± 1%   9.65GB/s ± 0%  +699.29%  (p=0.000 n=9+8)

Fixes #19411

Change-Id: I8d2d409f0fa6df6d03b60790aa86e540b4a4e3b0
Reviewed-on: https://go-review.googlesource.com/38693
Reviewed-by: Keith Randall <khr@golang.org>
2017-04-07 14:25:13 +00:00
Martin Möhrmann
bebfd4ba41 strings: speed up Fields
- use a string lookup to detect if a single byte is a space character
- determine the exact number of fields for ASCII and
  a possibly underestimated number of fields for non ASCII strings
  by doing a separate byte for byte scan of the input string
  before collecting the fields in an extra pass
- provide a fast path for ASCII only strings when collecting the fields
- avoid utf8.DecodeRuneInString and unicode.IsSpace for ASCII characters

Used golang.org/cl/33108 from Joe Tsai as starting point.

name                      old time/op    new time/op     delta
Fields/ASCII/16              284ns ± 1%      116ns ± 2%   -59.30%  (p=0.000 n=9+10)
Fields/ASCII/256            3.81µs ± 1%     0.80µs ± 1%   -79.10%  (p=0.000 n=10+10)
Fields/ASCII/4096           61.4µs ± 1%     12.3µs ± 1%   -79.96%  (p=0.000 n=10+9)
Fields/ASCII/65536           982µs ± 1%      235µs ± 0%   -76.04%  (p=0.000 n=10+9)
Fields/ASCII/1048576        16.7ms ± 2%      5.4ms ± 1%   -67.52%  (p=0.000 n=10+10)
Fields/Mixed/16              314ns ± 1%      168ns ± 1%   -46.33%  (p=0.000 n=9+10)
Fields/Mixed/256            3.92µs ± 1%     1.17µs ± 1%   -70.19%  (p=0.000 n=10+10)
Fields/Mixed/4096           69.1µs ± 1%     19.0µs ± 1%   -72.53%  (p=0.000 n=10+10)
Fields/Mixed/65536          1.12ms ± 1%     0.39ms ± 0%   -65.37%  (p=0.000 n=10+9)
Fields/Mixed/1048576        19.0ms ± 2%      7.3ms ± 4%   -61.75%  (p=0.000 n=10+9)

name                      old speed      new speed       delta
Fields/ASCII/16           56.3MB/s ± 1%  138.1MB/s ± 2%  +145.31%  (p=0.000 n=9+10)
Fields/ASCII/256          67.1MB/s ± 1%  321.0MB/s ± 1%  +378.26%  (p=0.000 n=10+10)
Fields/ASCII/4096         66.7MB/s ± 1%  333.0MB/s ± 1%  +398.97%  (p=0.000 n=10+9)
Fields/ASCII/65536        66.7MB/s ± 1%  278.4MB/s ± 0%  +317.39%  (p=0.000 n=10+9)
Fields/ASCII/1048576      62.7MB/s ± 2%  192.9MB/s ± 1%  +207.82%  (p=0.000 n=10+10)
Fields/Mixed/16           51.0MB/s ± 2%   94.9MB/s ± 1%   +85.87%  (p=0.000 n=10+10)
Fields/Mixed/256          65.4MB/s ± 1%  219.2MB/s ± 1%  +235.33%  (p=0.000 n=10+10)
Fields/Mixed/4096         59.3MB/s ± 1%  215.7MB/s ± 1%  +263.98%  (p=0.000 n=10+10)
Fields/Mixed/65536        58.6MB/s ± 1%  169.1MB/s ± 0%  +188.73%  (p=0.000 n=10+9)
Fields/Mixed/1048576      55.1MB/s ± 2%  144.0MB/s ± 4%  +161.44%  (p=0.000 n=10+9)

Updates #19789
Updates #17856

Change-Id: If2ce1479542702e9cd65a82a462ba55ac8eb3876
Reviewed-on: https://go-review.googlesource.com/37959
Run-TryBot: Martin Möhrmann <moehrmann@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
2017-04-04 06:26:11 +00:00
Eric Lagergren
59f6549d1c bytes, strings: declare variables inside loop they're used in
The recently updated Count functions declare variables before
special-cased returns.

Change-Id: I8f726118336b7b0ff72117d12adc48b6e37e60ea
Reviewed-on: https://go-review.googlesource.com/39357
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-04-03 23:30:36 +00:00
Martin Möhrmann
3c023f75a6 strings: fix handling of invalid UTF-8 sequences in Map
The new Map implementation introduced in golang.org/cl/33201
did not differentiate if an invalid UTF-8 sequence was decoded
or the RuneError rune. It would therefore always advance by
3 bytes (which is the length of the RuneError rune) instead
of 1 for an invalid sequences. This cl adds a check to correctly
determine the length of bytes needed to advance to the next rune.

Fixes #19330.

Change-Id: I1e7f9333f3ef6068ffc64015bb0a9f32b0b7111d
Reviewed-on: https://go-review.googlesource.com/37597
Run-TryBot: Martin Möhrmann <moehrmann@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-02-28 22:50:53 +00:00
Martin Möhrmann
4b3e6fe123 strings: speed up Map
name                  old time/op  new time/op  delta
ByteByteMap-4         2.03µs ± 2%  1.03µs ± 2%  -49.24%  (p=0.000 n=10+10)
Map/identity/ASCII-4   246ns ± 0%   158ns ± 0%  -35.90%    (p=0.000 n=9+9)
Map/identity/Greek-4   367ns ± 1%   273ns ± 1%  -25.63%  (p=0.000 n=10+10)
Map/change/ASCII-4     582ns ± 1%   324ns ± 1%  -44.34%  (p=0.000 n=10+10)
Map/change/Greek-4     709ns ± 2%   623ns ± 2%  -12.16%  (p=0.000 n=10+10)
MapNoChanges-4         171ns ± 1%   111ns ± 1%  -35.36%   (p=0.000 n=8+10)

Updates #17859

Change-Id: I55d7d261fdc1ce2dcd0ebe23b0fa20b9889bf54c
Reviewed-on: https://go-review.googlesource.com/33201
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-02-24 22:53:05 +00:00
Alberto Donizetti
272ec231b7 strings: make parameters names less confusing
Using 'sep' as parameter name for strings functions that take a
separator argument is fine, but for functions like Index or Count that
look for a substring it's better to use 'substr' (like Contains
already does).

Fixes #19039

Change-Id: Idd557409c8fea64ce830ab0e3fec37d3d56a79f0
Reviewed-on: https://go-review.googlesource.com/36874
Run-TryBot: Alberto Donizetti <alb.donizetti@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-02-11 19:55:21 +00:00
Aliaksandr Valialkin
8946502776 bytes, strings: optimize Split*
The relevant benchmark results on linux/amd64:

bytes:

SplitSingleByteSeparator-4   25.7ms ± 5%   9.1ms ± 4%  -64.40%  (p=0.000 n=10+10)
SplitMultiByteSeparator-4    13.8ms ±20%   4.3ms ± 8%  -69.23%  (p=0.000 n=10+10)
SplitNSingleByteSeparator-4  1.88µs ± 9%  0.88µs ± 4%  -53.25%  (p=0.000 n=10+10)
SplitNMultiByteSeparator-4   4.83µs ±10%  1.32µs ± 9%  -72.65%  (p=0.000 n=10+10)

strings:

name                         old time/op  new time/op  delta
SplitSingleByteSeparator-4   21.4ms ± 8%   8.5ms ± 5%  -60.19%  (p=0.000 n=10+10)
SplitMultiByteSeparator-4    13.2ms ± 9%   3.9ms ± 4%  -70.29%  (p=0.000 n=10+10)
SplitNSingleByteSeparator-4  1.54µs ± 5%  0.75µs ± 7%  -51.21%  (p=0.000 n=10+10)
SplitNMultiByteSeparator-4   3.57µs ± 8%  1.01µs ±11%  -71.76%  (p=0.000 n=10+10)

Fixes #18973

Change-Id: Ie4bc010c6cc389001e72eab530497c81e5b26f34
Reviewed-on: https://go-review.googlesource.com/36510
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-02-08 18:39:43 +00:00
Ilya Tocar
438818d9f1 bytes: use Index in Count
Similar to https://go-review.googlesource.com/28586,
but for package bytes instead of strings.
This provides simpler code and some performance gain.
Also update strings.Count to use the same code.

On AMD64 with heavily optimized Index I see:

name             old time/op    new time/op     delta
Count/10-6         47.3ns ± 0%     36.8ns ± 0%    -22.35%  (p=0.000 n=10+10)
Count/32-6          286ns ± 0%       38ns ± 0%    -86.71%  (p=0.000 n=10+10)
Count/4K-6         50.1µs ± 0%      4.4µs ± 0%    -91.18%  (p=0.000 n=10+10)
Count/4M-6         48.1ms ± 1%      4.5ms ± 0%    -90.56%  (p=0.000 n=10+9)
Count/64M-6         784ms ± 0%       73ms ± 0%    -90.73%  (p=0.000 n=10+10)
CountEasy/10-6     28.4ns ± 0%     31.0ns ± 0%     +9.23%  (p=0.000 n=10+10)
CountEasy/32-6     30.6ns ± 0%     37.0ns ± 0%    +20.92%  (p=0.000 n=10+10)
CountEasy/4K-6      186ns ± 0%      198ns ± 0%     +6.45%  (p=0.000 n=9+10)
CountEasy/4M-6      233µs ± 2%      234µs ± 2%       ~     (p=0.912 n=10+10)
CountEasy/64M-6    6.70ms ± 0%     6.68ms ± 1%       ~     (p=0.762 n=8+10)

name             old speed      new speed       delta
Count/10-6        211MB/s ± 0%    272MB/s ± 0%    +28.77%  (p=0.000 n=10+9)
Count/32-6        112MB/s ± 0%    842MB/s ± 0%   +652.84%  (p=0.000 n=10+10)
Count/4K-6       81.8MB/s ± 0%  927.6MB/s ± 0%  +1033.63%  (p=0.000 n=10+9)
Count/4M-6       87.2MB/s ± 1%  924.0MB/s ± 0%   +959.25%  (p=0.000 n=10+9)
Count/64M-6      85.6MB/s ± 0%  922.9MB/s ± 0%   +978.31%  (p=0.000 n=10+10)
CountEasy/10-6    352MB/s ± 0%    322MB/s ± 0%     -8.41%  (p=0.000 n=10+10)
CountEasy/32-6   1.05GB/s ± 0%   0.87GB/s ± 0%    -17.35%  (p=0.000 n=9+10)
CountEasy/4K-6   22.0GB/s ± 0%   20.6GB/s ± 0%     -6.33%  (p=0.000 n=10+10)
CountEasy/4M-6   18.0GB/s ± 2%   18.0GB/s ± 2%       ~     (p=0.912 n=10+10)
CountEasy/64M-6  10.0GB/s ± 0%   10.0GB/s ± 1%       ~     (p=0.762 n=8+10)

On 386, without asm version of Index:

Count/10-6         57.0ns ± 0%     56.9ns ± 0%   -0.11%  (p=0.006 n=10+9)
Count/32-6          340ns ± 0%      274ns ± 0%  -19.48%  (p=0.000 n=10+9)
Count/4K-6         49.5µs ± 0%     37.1µs ± 0%  -24.96%  (p=0.000 n=10+10)
Count/4M-6         51.1ms ± 0%     38.2ms ± 0%  -25.21%  (p=0.000 n=10+10)
Count/64M-6         818ms ± 0%      613ms ± 0%  -25.07%  (p=0.000 n=8+10)
CountEasy/10-6     60.0ns ± 0%     70.4ns ± 0%  +17.34%  (p=0.000 n=10+10)
CountEasy/32-6     81.1ns ± 0%     94.0ns ± 0%  +15.97%  (p=0.000 n=9+10)
CountEasy/4K-6     4.37µs ± 0%     4.39µs ± 0%   +0.30%  (p=0.000 n=10+9)
CountEasy/4M-6     4.43ms ± 0%     4.43ms ± 0%     ~     (p=0.579 n=10+10)
CountEasy/64M-6    70.9ms ± 0%     70.9ms ± 0%     ~     (p=0.912 n=10+10)

name             old speed      new speed       delta
Count/10-6        176MB/s ± 0%    176MB/s ± 0%   +0.10%  (p=0.000 n=10+9)
Count/32-6       93.9MB/s ± 0%  116.5MB/s ± 0%  +24.06%  (p=0.000 n=10+9)
Count/4K-6       82.7MB/s ± 0%  110.3MB/s ± 0%  +33.26%  (p=0.000 n=10+10)
Count/4M-6       82.1MB/s ± 0%  109.7MB/s ± 0%  +33.70%  (p=0.000 n=10+10)
Count/64M-6      82.0MB/s ± 0%  109.5MB/s ± 0%  +33.46%  (p=0.000 n=8+10)
CountEasy/10-6    167MB/s ± 0%    142MB/s ± 0%  -14.75%  (p=0.000 n=9+10)
CountEasy/32-6    395MB/s ± 0%    340MB/s ± 0%  -13.77%  (p=0.000 n=10+10)
CountEasy/4K-6    936MB/s ± 0%    934MB/s ± 0%   -0.29%  (p=0.000 n=10+9)
CountEasy/4M-6    947MB/s ± 0%    946MB/s ± 0%     ~     (p=0.591 n=10+10)
CountEasy/64M-6   947MB/s ± 0%    947MB/s ± 0%     ~     (p=0.867 n=10+10)

Change-Id: Ia76b247372b6f5b5d23a9f10253a86536a5153b3
Reviewed-on: https://go-review.googlesource.com/36489
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2017-02-08 17:52:30 +00:00
Joe Tsai
9a8c69539c bytes, strings: optimize for ASCII sets
In a large codebase within Google, there are thousands of uses of:
	ContainsAny|IndexAny|LastIndexAny|Trim|TrimLeft|TrimRight

An analysis of their usage shows that over 97% of them only use character
sets consisting of only ASCII symbols.

Uses of ContainsAny|IndexAny|LastIndexAny:
	 6% are 1   character  (e.g., "\n" or " ")
	58% are 2-4 characters (e.g., "<>" or "\r\n\t ")
	24% are 5-9 characters (e.g., "()[]*^$")
	10% are 10+ characters (e.g., "+-=&|><!(){}[]^\"~*?:\\/ ")
We optimize for ASCII sets, which are commonly used to search for
"control" characters in some string. We don't optimize for the
single character scenario since IndexRune or IndexByte could be used.

Uses of Trim|TrimLeft|TrimRight:
	71% are 1   character  (e.g., "\n" or " ")
	14% are 2   characters (e.g., "\r\n")
	10% are 3-4 characters (e.g., " \t\r\n")
	 5% are 10+ characters (e.g., "0123456789abcdefABCDEF")
We optimize for the single character case with a simple closured function
that only checks for that character's value. We optimize for the medium
and larger sets using a 16-byte bit-map representing a set of ASCII characters.

The benchmarks below have the following suffix name "%d:%d" where the first
number is the length of the input and the second number is the length
of the charset.

== bytes package ==
benchmark                            old ns/op     new ns/op     delta
BenchmarkIndexAnyASCII/1:1-4         5.09          5.23          +2.75%
BenchmarkIndexAnyASCII/1:2-4         5.81          5.85          +0.69%
BenchmarkIndexAnyASCII/1:4-4         7.22          7.50          +3.88%
BenchmarkIndexAnyASCII/1:8-4         11.0          11.1          +0.91%
BenchmarkIndexAnyASCII/1:16-4        17.5          17.8          +1.71%
BenchmarkIndexAnyASCII/16:1-4        36.0          34.0          -5.56%
BenchmarkIndexAnyASCII/16:2-4        46.6          36.5          -21.67%
BenchmarkIndexAnyASCII/16:4-4        78.0          40.4          -48.21%
BenchmarkIndexAnyASCII/16:8-4        136           47.4          -65.15%
BenchmarkIndexAnyASCII/16:16-4       254           61.5          -75.79%
BenchmarkIndexAnyASCII/256:1-4       542           388           -28.41%
BenchmarkIndexAnyASCII/256:2-4       705           382           -45.82%
BenchmarkIndexAnyASCII/256:4-4       1089          386           -64.55%
BenchmarkIndexAnyASCII/256:8-4       1994          394           -80.24%
BenchmarkIndexAnyASCII/256:16-4      3843          411           -89.31%
BenchmarkIndexAnyASCII/4096:1-4      8522          5873          -31.08%
BenchmarkIndexAnyASCII/4096:2-4      11253         5861          -47.92%
BenchmarkIndexAnyASCII/4096:4-4      17824         5883          -66.99%
BenchmarkIndexAnyASCII/4096:8-4      32053         5871          -81.68%
BenchmarkIndexAnyASCII/4096:16-4     60512         5888          -90.27%
BenchmarkTrimASCII/1:1-4             79.5          70.8          -10.94%
BenchmarkTrimASCII/1:2-4             79.0          105           +32.91%
BenchmarkTrimASCII/1:4-4             79.6          109           +36.93%
BenchmarkTrimASCII/1:8-4             78.8          118           +49.75%
BenchmarkTrimASCII/1:16-4            80.2          132           +64.59%
BenchmarkTrimASCII/16:1-4            243           116           -52.26%
BenchmarkTrimASCII/16:2-4            243           171           -29.63%
BenchmarkTrimASCII/16:4-4            243           176           -27.57%
BenchmarkTrimASCII/16:8-4            241           184           -23.65%
BenchmarkTrimASCII/16:16-4           238           199           -16.39%
BenchmarkTrimASCII/256:1-4           2580          840           -67.44%
BenchmarkTrimASCII/256:2-4           2603          1175          -54.86%
BenchmarkTrimASCII/256:4-4           2572          1188          -53.81%
BenchmarkTrimASCII/256:8-4           2550          1191          -53.29%
BenchmarkTrimASCII/256:16-4          2585          1208          -53.27%
BenchmarkTrimASCII/4096:1-4          39773         12181         -69.37%
BenchmarkTrimASCII/4096:2-4          39946         17231         -56.86%
BenchmarkTrimASCII/4096:4-4          39641         17179         -56.66%
BenchmarkTrimASCII/4096:8-4          39835         17175         -56.88%
BenchmarkTrimASCII/4096:16-4         40229         17215         -57.21%

== strings package ==
benchmark                            old ns/op     new ns/op     delta
BenchmarkIndexAnyASCII/1:1-4         5.94          4.97          -16.33%
BenchmarkIndexAnyASCII/1:2-4         5.94          5.55          -6.57%
BenchmarkIndexAnyASCII/1:4-4         7.45          7.21          -3.22%
BenchmarkIndexAnyASCII/1:8-4         10.8          10.6          -1.85%
BenchmarkIndexAnyASCII/1:16-4        17.4          17.2          -1.15%
BenchmarkIndexAnyASCII/16:1-4        36.4          32.2          -11.54%
BenchmarkIndexAnyASCII/16:2-4        49.6          34.6          -30.24%
BenchmarkIndexAnyASCII/16:4-4        77.5          37.9          -51.10%
BenchmarkIndexAnyASCII/16:8-4        138           45.5          -67.03%
BenchmarkIndexAnyASCII/16:16-4       241           59.1          -75.48%
BenchmarkIndexAnyASCII/256:1-4       509           378           -25.74%
BenchmarkIndexAnyASCII/256:2-4       720           381           -47.08%
BenchmarkIndexAnyASCII/256:4-4       1142          384           -66.37%
BenchmarkIndexAnyASCII/256:8-4       1999          391           -80.44%
BenchmarkIndexAnyASCII/256:16-4      3735          403           -89.21%
BenchmarkIndexAnyASCII/4096:1-4      7973          5824          -26.95%
BenchmarkIndexAnyASCII/4096:2-4      11432         5809          -49.19%
BenchmarkIndexAnyASCII/4096:4-4      18327         5819          -68.25%
BenchmarkIndexAnyASCII/4096:8-4      33059         5828          -82.37%
BenchmarkIndexAnyASCII/4096:16-4     59703         5817          -90.26%
BenchmarkTrimASCII/1:1-4             71.9          71.8          -0.14%
BenchmarkTrimASCII/1:2-4             73.3          103           +40.52%
BenchmarkTrimASCII/1:4-4             71.8          106           +47.63%
BenchmarkTrimASCII/1:8-4             71.2          113           +58.71%
BenchmarkTrimASCII/1:16-4            71.6          128           +78.77%
BenchmarkTrimASCII/16:1-4            152           116           -23.68%
BenchmarkTrimASCII/16:2-4            160           168           +5.00%
BenchmarkTrimASCII/16:4-4            172           170           -1.16%
BenchmarkTrimASCII/16:8-4            200           177           -11.50%
BenchmarkTrimASCII/16:16-4           254           193           -24.02%
BenchmarkTrimASCII/256:1-4           1438          864           -39.92%
BenchmarkTrimASCII/256:2-4           1551          1195          -22.95%
BenchmarkTrimASCII/256:4-4           1770          1200          -32.20%
BenchmarkTrimASCII/256:8-4           2195          1216          -44.60%
BenchmarkTrimASCII/256:16-4          3054          1224          -59.92%
BenchmarkTrimASCII/4096:1-4          21726         12557         -42.20%
BenchmarkTrimASCII/4096:2-4          23586         17508         -25.77%
BenchmarkTrimASCII/4096:4-4          26898         17510         -34.90%
BenchmarkTrimASCII/4096:8-4          33714         17595         -47.81%
BenchmarkTrimASCII/4096:16-4         47429         17700         -62.68%

The benchmarks added test the worst case. For IndexAny, that is when the
charset matches none of the input. For Trim, it is when the charset matches
all of the input.

Change-Id: I970874d101a96b33528fc99b165379abe58cf6ea
Reviewed-on: https://go-review.googlesource.com/31593
Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Martin Möhrmann <martisch@uos.de>
2016-10-28 17:37:04 +00:00
Joe Tsai
4b2665786e bytes, strings: fix regression in IndexRune
In all previous versions of Go, the behavior of IndexRune(s, r)
where r was utf.RuneError was that it would effectively return the
index of any invalid UTF-8 byte sequence (include RuneError).
Optimizations made in http://golang.org/cl/28537 and
http://golang.org/cl/28546 altered this undocumented behavior such
that RuneError would only match on the RuneError rune itself.

Although, the new behavior is arguably reasonable, it did break code
that depended on the previous behavior. Thus, we add special checks
to ensure that we preserve the old behavior.

There is a slight performance hit for correctness:
	benchmark                   old ns/op     new ns/op     delta
	BenchmarkIndexRune/10-4     19.3          21.6          +11.92%
	BenchmarkIndexRune/32-4     33.6          35.2          +4.76%
This only occurs on small strings. The performance hit for larger strings
is neglible and not shown.

Fixes #17611

Change-Id: I1d863a741213d46c40b2e1724c41245df52502a5
Reviewed-on: https://go-review.googlesource.com/32123
Run-TryBot: Joe Tsai <thebrokentoaster@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-10-26 23:02:27 +00:00
Joe Tsai
03361fd350 bytes, strings: fix snake-case in variable name
Change-Id: I40896fffbffefa359d08abda346933aa996f628d
Reviewed-on: https://go-review.googlesource.com/32124
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-10-26 21:51:48 +00:00
Ilya Tocar
6347367be3 strings: use Index in Count
This simplifies code and provides performance iprovments:
Similar to https://go-review.googlesource.com/#/c/28577

CountHard1-48               1.74ms ±14%  0.17ms ±14%  -90.16%  (p=0.000 n=19+19)
CountHard2-48               1.78ms ±15%  0.25ms ±13%  -86.10%  (p=0.000 n=19+20)
CountHard3-48               1.78ms ±12%  0.80ms ±11%  -55.19%  (p=0.000 n=17+20)
CountTorture-48             13.5µs ±14%  13.6µs ±11%     ~     (p=0.625 n=18+19)
CountTortureOverlapping-48  6.92ms ±13%  8.42ms ±11%  +21.72%  (p=0.000 n=19+17)

Change-Id: Ief120aee918a66487c76be56e0796871c8502f89
Reviewed-on: https://go-review.googlesource.com/28586
Run-TryBot: Ilya Tocar <ilya.tocar@intel.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-10-15 16:39:31 +00:00
Emmanuel Odeke
7b40b0c3a3 strings, bytes: panic if Repeat overflows or if given a negative count
Panic if Repeat is given a negative count or
if the value of (len(*) * count) is detected
to overflow.
We panic because we cannot change the
signature of Repeat to return an error.

Fixes #16237

Change-Id: I9f5ba031a5b8533db0582d7a672ffb715143f3fb
Reviewed-on: https://go-review.googlesource.com/29954
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2016-10-01 15:47:35 +00:00
Hiroshi Ioka
8737dac1f2 strings: make IndexRune faster
re-implement IndexRune by Index which is well optimized to get
performance gain.

name                   old time/op  new time/op  delta
IndexRune-4            30.2ns ± 1%  28.3ns ± 1%   -6.22%  (p=0.000 n=20+19)
IndexRuneLongString-4   156ns ± 1%    49ns ± 1%  -68.72%  (p=0.000 n=19+19)
IndexRuneFastPath-4    10.6ns ± 2%  10.0ns ± 1%   -6.30%  (p=0.000 n=18+18)

Change-Id: Ie663b8f7860ca51892dd4be182fca3caa5f8ae61
Reviewed-on: https://go-review.googlesource.com/28546
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-09-07 01:03:10 +00:00