
рдЖрдЬ рд╣рдо рдЧреЛ рдореЗрдВ 30% рдЫреЛрдЯреА рд▓рд╛рдЗрдиреЛрдВ рдХреА рдмреЙрдиреНрдбрд┐рдВрдЧ рдХреЛ рддреЗрдЬ рдХрд░реЗрдВрдЧреЗред рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рд╣рдореЗрдВ рд╕реНрд╡рдпрдВ рдЧреЛ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрдЧреА, рдпрд╣ рд╕рдм рддреАрд╕рд░реЗ рдкрдХреНрд╖ рдХреЗ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рд░реВрдк рдореЗрдВ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
рдЙрд╕ рдХрдЯреМрддреА рдХреЗ рддрд╣рдд рдЬрд┐рд╕рдХрд╛ рдЖрдк рдЗрдВрддрдЬрд╛рд░ рдХрд░ рд░рд╣реЗ рд╣реИрдВ:
- рддреБрд▓рдирд╛
+
, strings.Builder
рдФрд░ рджреЗрд╢реА рд╕рдВрдШрдирди рдХрд╛рд░реНрдп - рдЖрдВрддрд░рд┐рдХ рдкрдВрдХреНрддрд┐ рд╡рд┐рд╡рд░рдг рдкрд░ рдЬрд╛рдПрдВ
- рдереЛрдбрд╝рд╛ рдЕрд╕реЗрдВрдмрд▓ рдХрд░реЗрдВ
рдЗрд╕ рд▓реЗрдЦ рдХреЛ CL123256 рдкрд░ рдЪрд░реНрдЪрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдмрд╣рд╛рдирд╛ рднреА рдорд╛рдирд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ : рд░рдирдЯрд╛рдЗрдо, cmd / рд╕рдВрдХрд▓рди: concatstring2 рд╡рд┐рд╢реЗрд╖рдЬреНрдЮ ред рдЗрд╕ рдкрд░рд┐рд╡рд░реНрддрди рд╕реВрдЪреА рдореЗрдВ рд╕реБрдзрд╛рд░ рдХреЗ рд▓рд┐рдП рд╡рд┐рдЪрд╛рд░реЛрдВ рдХрд╛ рд╕реНрд╡рд╛рдЧрдд рд╣реИред
рддреБрд░рдВрдд рдкрд░рд┐рдгрд╛рдо
рдХрдВрдкрд╛рдЗрд▓рд░ рдХреЗ go tip
(рдорд╛рд╕реНрдЯрд░) рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд╕рд╛рде рддреБрд▓рдирд╛ рдХреА рдЧрдИ рдереАред рдЖрдк рдЧреЛ 1.5 рдХреЗ рдЖрд╕рдкрд╛рд╕ рд╕рдВрд╕реНрдХрд░рдгреЛрдВ рдкрд░ рд╕рдорд╛рди рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред concatstrings
рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдП рдЕрдВрддрд┐рдо рдорд╣рддреНрд╡рдкреВрд░реНрдг рдкрд░рд┐рд╡рд░реНрддрди CL3120: cmd / gc рдерд╛: рд╕реНрдЯреИрдХ рдкрд░ рдЧреИрд░-рдПрд╕реНрдХреЗрдк рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдХреЗ рд▓рд┐рдП рдмрдлрд╝рд░реНрд╕ рдЖрд╡рдВрдЯрд┐рдд рдХрд░реЗрдВ ред
BenchmarkConcat2Operator-8 20000000 83.8 ns/op BenchmarkConcat2Builder-8 20000000 70.9 ns/op BenchmarkConcat2-8 20000000 62.1 ns/op BenchmarkConcat3Operator-8 20000000 104 ns/op BenchmarkConcat3Builder-8 20000000 89.9 ns/op BenchmarkConcat3-8 20000000 82.1 ns/op
ConcatOperator
+
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред
ConcatBuilder
рд╕рд╣реА рдкреВрд░реНрд╡-рдЖрд╡рдВрдЯрди рдХреЗ рд╕рд╛рде ConcatBuilder
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред
Concat
рдЙрд╕ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рд╣рдо рдЗрд╕ рдХрд╣рд╛рдиреА рдХреЗ рд╣рд┐рд╕реНрд╕реЗ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрд░рддреЗ рд╣реИрдВред
рдмреЗрдВрдЪрд╕реНрдЯреИрдЯ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рддреБрд▓рдирд╛:
name old time/op new time/op delta Concat2-8 84.2ns ┬▒ 1% 62.7ns ┬▒ 2% -25.49% (p=0.000 n=9+10) Concat3-8 103ns ┬▒ 3% 83ns ┬▒ 4% -19.83% (p=0.000 n=10+9)
GOARCH=AMD64
рддрд╣рдд рдХреЛрдбрд╛рдВрддрд░рдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдереЛрдбрд╝рд╛ рддреЗрдЬ рд╣реИ рдФрд░ рдЗрд╕рдореЗрдВ рдЕрддрд┐рд░рд┐рдХреНрдд рдЕрдиреБрдХреВрд▓рди рд╣реИ, рдЬреЛ рдмрд┐рд▓реНрдЯ-рдЗрди +
рдСрдкрд░реЗрдЯрд░ рдореЗрдВ рдореМрдЬреВрдж рд╣реИ, рд▓реЗрдХрд┐рди рдиреАрдЪреЗ рдЙрд╕ рдкрд░ рдФрд░ рдЕрдзрд┐рдХ:
name old time/op new time/op delta Concat2-8 84.2ns ┬▒ 1% 57.1ns ┬▒ 3% -32.20% (p=0.000 n=9+9)
рд╣рдо рдЕрд╕реЗрдВрдмрд▓рд░ рдлрд╝рдВрдХреНрд╢рди рдХреЛ 100% рдкреНрд░рджрд░реНрд╢рди (рд╢реЗрд╖ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖) рдХреЗ рд░реВрдк рдореЗрдВ рд▓реЗрдВрдЧреЗред
рд▓рдВрдмреА рд▓рд╛рдЗрдиреЛрдВ рдХреЗ рдкрд░рд┐рдгрд╛рдо README.md рдореЗрдВ рджреЗрдЦреЗ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред рд╕реНрдЯреНрд░рд┐рдВрдЧ рдЬрд┐рддрдиреА рд▓рдВрдмреА рд╣реЛрдЧреА, рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рдмреАрдЪ рдХрд╛ рдЕрдВрддрд░ рдЙрддрдирд╛ рд╣реА рдХрдо рд╣реЛрдЧрд╛ред
рднреЛрд▓рд╛рдкрди
рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рдЙрдкрд╛рдп рд╣реИ +
рдСрдкрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ред
рдЗрд╕ рдХрдерди рдХреЗ рд╢рдмреНрджрд╛рд░реНрде рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИрдВ: рджреЛ рдкрдВрдХреНрддрд┐рдпрд╛рдБ рд▓реЗрдВ рдФрд░ рдПрдХ рдкрд░рд┐рдгрд╛рдо рд╕реНрдЯреНрд░рд┐рдВрдЧ рд▓реМрдЯрд╛рдПрдБ рдЬрд┐рд╕рдореЗрдВ рджреЛрдиреЛрдВ рд░реЗрдЦрд╛рдУрдВ рдХрд╛ рд╕рдВрдШрд╛рдд рд╣реЛред рдЗрд╕ рдмрд╛рдд рдХреА рдХреЛрдИ рдЧрд╛рд░рдВрдЯреА рдирд╣реАрдВ рд╣реИ рдХрд┐ рдПрдХ рдирдИ рд▓рд╛рдЗрди рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рдПрдЧреАред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рдЦрд╛рд▓реА рд╕реНрдЯреНрд░рд┐рдВрдЧ рдФрд░ рдХрд┐рд╕реА рднреА рдЕрдиреНрдп рдХрд╛ рд╕рдВрдпреЛрдЬрди рд╣реИ, рддреЛ рд░рдирдЯрд╛рдЗрдо рдПрдХ рдЧреИрд░-рд░рд┐рдХреНрдд рддрд░реНрдХ рд▓реМрдЯрд╛ рд╕рдХрддрд╛ рд╣реИ, рдирдИ рдореЗрдореЛрд░реА рдХреЛ рдЖрд╡рдВрдЯрд┐рдд рдХрд░рдиреЗ рдФрд░ рд╡рд╣рд╛рдВ рдбреЗрдЯрд╛ рдХреЙрдкреА рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╕реЗ рдмрдЪрддрд╛ рд╣реИред
рд▓реЗрдХрд┐рди, рдЬреИрд╕рд╛ рдХрд┐ рд▓реЗрдЦ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдкрд░рд┐рдгрд╛рдореЛрдВ рд╕реЗ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдпрд╣ рд╕рдмрд╕реЗ рдзреАрдорд╛ рддрд░реАрдХрд╛ рд╣реИред
func concat2operator(x, y string) string { return x + y }
рдкреНрд░рджрд░реНрд╢рди рд░реЗрдЯрд┐рдВрдЧ: 67.8% ред
strings.Builder
рдмрд╣реБрдд рд╕рдордп рдкрд╣рд▓реЗ рдирд╣реАрдВ, рдЧреЛ - рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдХреЗ рд▓рд┐рдП рдПрдХ рдирдпрд╛ рдкреНрд░рдХрд╛рд░ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рдерд╛ред рдпрд╣ bytes.Buffer
рдХрд╛ рдПрдХ рдПрдирд╛рд▓реЙрдЧ рд╣реИред bytes.Buffer
, рд▓реЗрдХрд┐рди String()
рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рддреЗ рд╕рдордп, рдореЗрдореЛрд░реА рдХреЛ рдлрд┐рд░ рд╕реЗ рдЖрд╡рдВрдЯрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдбреЗрдЯрд╛ рдХреА рдкреНрд░рддрд┐рд▓рд┐рдкрд┐ рдирд╣реАрдВ рдмрдирд╛рдИ рдЬрд╛рддреА рд╣реИред
bytes.Buffer
рд╡рд┐рдкрд░реАрддред bytes.Buffer
, рдмрд┐рд▓реНрдбрд░ рдХреЗ рдкрд╛рд╕ рдПрдХ рдЫреЛрдЯреЗ рдмрдлрд░ рдХрд╛ рдЕрдиреБрдХреВрд▓рди рдирд╣реАрдВ рд╣реИ рдФрд░ рдЗрд╕рд▓рд┐рдП, рдкрд╣рд▓реЗ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдЖрд╡рдВрдЯрд┐рдд рдореЗрдореЛрд░реАред рдпрджрд┐ рдЖрдк Grow
рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдкреНрд░рджрд░реНрд╢рди bytes.Buffer
рд╕реЗ рднреА рдмрджрддрд░ рд╣реЛрдЧрд╛ред bytes.Buffer
ред рдЧреЛ 1.11 рдореЗрдВ рдХрдИ рд░реЗрдЬрд┐рд╕реНрдЯрд░ рдЗрд╕ рд╡рд┐рд╢реЗрд╖ рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рдХрд╛рд░рдг рд╣реЛрддреЗ рд╣реИрдВ ( CL113235 рджреЗрдЦреЗрдВ)ред
рд╣рдорд╛рд░реЗ рдХреЛрдб рдореЗрдВ, рдкреНрд░рдпреЛрдЧ рдХреА рд╢реБрджреНрдзрддрд╛ рдХреЗ рд▓рд┐рдП, рд╣рдо рдЗрд╕ рддреНрд░реБрдЯрд┐ рд╕реЗ рдмрдЪреЗрдВрдЧреЗред
func concat2builder(x, y string) string { var builder strings.Builder builder.Grow(len(x) + len(y))
рдкреНрд░рджрд░реНрд╢рди рд░реЗрдЯрд┐рдВрдЧ: 80.5% (+12.7)ред
рдХреЙрдирдЯреИрдЯрди рдХреЗ рд▓рд┐рдП рдХреЛрдб рдЬрдирд░реЗрд╢рди
рдпрджрд┐ рд╣рдо рджреЗрдЦрддреЗ рд╣реИрдВ рдХрд┐ рдХрдВрдкрд╛рдЗрд▓рд░ +
рдСрдкрд░реЗрдЯрд░ рдХреЗ рд▓рд┐рдП рдХрд┐рд╕ рдХреЛрдб рдХреЛ рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ, рддреЛ рд╣рдо concatstring2
, concatstring3
concatstring2
рдХреЛ рдХреЙрд▓ рдХрд░реЗрдВрдЧреЗ, рдФрд░ рдЗрд╕реА рддрд░рд╣ ( concatstring5
рд╕рдорд╛рд╡реЗрд╢реА рддрдХ)ред
func concat2codegen(x, y) string { return x + y }
рд╕реНрд╡рдпрдВ рд░рдирдЯрд╛рдЗрдо / рд╕реНрдЯреНрд░рд┐рдВрдЧ рдкрд░ рдПрдХ рдирдЬрд╝рд░ рдбрд╛рд▓реЗрдВ:
func concatstring2(buf *tmpBuf, a [2]string) string { return concatstrings(buf, a[:]) } func concatstring3(buf *tmpBuf, a [3]string) string { return concatstrings(buf, a[:]) }
рдЗрд╕рд▓рд┐рдП, рдпрд╣ рдлрдВрдХреНрд╢рди concatstrings
рд╕реАрдЦрдирд╛ concatstrings
ред
рд╕реНрдкреЙрдЗрд▓рд░ рдХреЗ рдиреАрдЪреЗ рдПрдХ рдкреВрд░реА рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ рдЙрдкрд▓рдмреНрдз рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣рд╛рдВ рдПрдХ рдЙрдЪреНрдЪ-рд╕реНрддрд░реАрдп рд╡рд┐рд╡рд░рдг рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:
buf
рдкреИрд░рд╛рдореАрдЯрд░ nil
рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рдмрдлрд░ рд╕рдВрдХрд▓рдХ рджреНрд╡рд╛рд░рд╛ рдЖрд╡рдВрдЯрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдпрджрд┐ рд░реЗрдЦрд╛ рдЕрдкрдиреА рдкрд░рд┐рднрд╛рд╖рд╛ рд╕реЗ "рдмрдЪ" рдирд╣реАрдВ рдЬрд╛рддреА рд╣реИред рдпрджрд┐ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдлреНрд░реЗрдо рд╕реЗ рдЕрдзрд┐рдХ рд╕рдордп рддрдХ рд░рд╣рддреА рд╣реИ, рддреЛ рдпрд╣ рдмрдлрд░ рд╣рдореЗрд╢рд╛ nil
(рдЬреИрд╕рд╛ рдХрд┐ рдЕрдХреНрд╕рд░ рд╣реЛрддрд╛ рд╣реИ)ред рд╣рд╛рд▓рд╛рдБрдХрд┐, рдпрджрд┐ рдпрд╣ рдмрдлрд╝рд░ рдЙрдкрд▓рдмреНрдз рд╣реИ, рддреЛ рдкрд░рд┐рдгрд╛рдо рдХреЗ рдЖрдмрдВрдЯрди рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрднрд╡ рд╣реЛрдЧрд╛, рдЬрдм рдкрд░рд┐рдгрд╛рдо рдЗрд╕рдореЗрдВ рдЯреВрдЯрддрд╛ рд╣реИ (рдЗрд╕рдХрд╛ рдЖрдХрд╛рд░ 32 рдмрд╛рдЗрдЯреНрд╕ рд╣реИ)ред- рдпрджрд┐ рдПрдХ рдХреЛ рдЫреЛрдбрд╝рдХрд░ рд╕рднреА рд▓рд╛рдЗрдиреЗрдВ рдЦрд╛рд▓реА рд╣реИрдВ, рддреЛ рдлрд╝рдВрдХреНрд╢рди рдЗрд╕ рд▓рд╛рдЗрди рдХреЛ рд╡рд╛рдкрд╕ рдХрд░ рджреЗрдЧрд╛ред рд▓реЗрдХрд┐рди рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ, рд╕реНрдЯреИрдХ рдкрд░ рдЪрдпрдирд┐рдд рд▓рд╛рдЗрдиреЛрдВ рдФрд░ рдЙрдирдХреЗ рдлреНрд░реЗрдо рдХреЛ рдЫреЛрдбрд╝рдХрд░ рдЗрд╕ рдЕрдиреБрдХреВрд▓рди рдХреЛ рдмрд╛рдпрдкрд╛рд╕ рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рддрд╛рдХрд┐ рдХреЙрд▓рд░ рдХреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдореБрдХреНрдд рдореЗрдореЛрд░реА рдкреНрд░рд╛рдкреНрдд рди рд╣реЛред
- рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╕рднреА рд▓рд╛рдЗрдиреЛрдВ рдХреЛ рдирдИ рдореЗрдореЛрд░реА рдореЗрдВ рдХреЙрдкреА рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рд╕рдореНтАНрдорд┐рд▓рди рд╕рдорд╛рд░реЛрд╣ рдХреА рдкреВрд░реА рд╕реВрдЪреА рдпрд╣рд╛рдБ рд╣рдо рдПрдХ рд╕рд╛рде рдХрдИ рд╕реНрдерд╛рдиреЛрдВ рдХреЛ рджреЗрдЦрддреЗ рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдХрд┐рд╕реА рд╡рд┐рд╢реЗрд╖ рдорд╛рдорд▓реЗ рдХреЗ рд▓рд┐рдП рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
buf
рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рдмрд╛рд░ рдЦрд╛рд▓реА рд╣реЛрддрд╛ рд╣реИред рдЬрдм рдХрдВрдкрд╛рдЗрд▓рд░ рдпрд╣ рд╕рд╛рдмрд┐рдд рдирд╣реАрдВ рдХрд░ рд╕рдХрд╛ рдХрд┐ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЛ рд╕реНрдЯреИрдХ рдкрд░ рд░рдЦрдиреЗ рдХреЗ рд▓рд┐рдП рд╕реБрд░рдХреНрд╖рд┐рдд рд╣реИ, рддреЛ рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдкреИрд░рд╛рдореАрдЯрд░ рдкрд╛рд╕ рдХрд░рдирд╛ рдФрд░ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдЕрдВрджрд░ nil
рд▓рд┐рдП рдЗрд╕реЗ рдЬрд╛рдВрдЪрдирд╛ рдХреЗрд╡рд▓ рдУрд╡рд░рд╣реЗрдб рджреЗрддрд╛ рд╣реИредlen(a) == 2
рд╕рд╛рде рд╡рд┐рд╢реЗрд╖ рдорд╛рдорд▓реЗ рдХреЗ рд▓рд┐рдП len(a) == 2
рд╣рдореЗрдВ рдПрдХ рдЪрдХреНрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ рдФрд░ рдЧрдгрдирд╛ рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдФрд░ рдпрд╣ рд╕рдВрдШрдирди рдХрд╛ рд╕рдмрд╕реЗ рдЖрдо рд░реВрдк рд╣реИред
рд╕рдВрдШрдЯрди рдХреЗ рдЖрдБрдХрдбрд╝реЗрдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рддреЗ рд╕рдордп ./make.bash
(рдЧреЛ рд╕рдВрдХрд▓рдХ рдФрд░ stdlib рдХрд╛ ./make.bash
) рд╣рдо рджреЛ рдСрдкрд░реЗрдВрдб рдХреЗ рд╕рд╛рде 445 рд╕рдВрдпреЛрдЬрди рджреЗрдЦрддреЗ рд╣реИрдВ:
- 398 рдкрд░рд┐рдгрд╛рдо рднрд╛рдЧ рд░рд╣реЗ рд╣реИрдВред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдорд╛рд░реА рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рд╕рдордЭ рдореЗрдВ рдЖрддреА рд╣реИред
- 47 рдкрд░рд┐рдгрд╛рдо рдЖрдкрдХреЗ рдлреНрд░реЗрдо рдХреЛ рдирд╣реАрдВ рдЫреЛрдбрд╝рддреЗ рд╣реИрдВред
рджреЛ рддрд░реНрдХреЛрдВ рд╕реЗ рдХреБрд▓ 89% рд╕рдВрдШрдирди рдкрд╕реАрдирд╛ рдЕрдиреБрдХреВрд▓рди рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред
go
рдЙрдкрдпреЛрдЧрд┐рддрд╛ рдХреЗ рд▓рд┐рдП, рд╣рдорд╛рд░реЗ рдкрд╛рд╕:
- 501 рдХреЙрд▓ рдХреЙрдиреНрд╕реНрдЯреНрд░реЗрд╕реНрдЯрд┐рдВрдЧ 2
- 194 рдХреЙрд▓ рдХреЙрдиреНрд╕реНрдЯреНрд░реЗрд╕реНрдЯрд┐рдВрдЧ 3
- 55 рдХреЙрд▓ рдХреЙрдиреНрдЯреНрд░рд╛рд╕реНрдЯреНрд░рд┐рдВрдЧ 4
рд╕рднреА рдЖрд░реНрдХрд┐рдЯреЗрдХреНрдЪрд░ рдХреЗ рд▓рд┐рдП рд╕рдВрд╕реНрдХрд░рдг
рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдпрд╣ рдЬрд╛рдирдирд╛ рд╣реЛрдЧрд╛ рдХрд┐ рдЧреЛ рдореЗрдВ рд▓рд╛рдЗрдиреЛрдВ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рджреНрд╡рд┐рдЖрдзрд╛рд░реА рд╕рдВрдЧрддрддрд╛ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИ, рдЬрдмрдХрд┐ unsafe.Pointer
рдмрд┐рдирд╛ рдХрд┐рд╕реА рдмрд▓рд┐рджрд╛рди рдХреЗ *byte
рд╕рд╛рде рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
type stringStruct struct { str *byte len int }
рджреВрд╕рд░рд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдирд┐рд╖реНрдХрд░реНрд╖ рдЬрд┐рд╕реЗ рд╣рдо рд░рдирдЯрд╛рдЗрдо рд╕реЗ рдЖрдХрд░реНрд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ: рд▓рд╛рдЗрдиреЗрдВ рдЙрдирдХреЗ рдЬреАрд╡рди рдХреЛ рдкрд░рд╕реНрдкрд░ рд░реВрдк рд╕реЗ рд╢реБрд░реВ рдХрд░рддреА рд╣реИрдВред рдореЗрдореЛрд░реА рдХрд╛ рдПрдХ рдЯреБрдХрдбрд╝рд╛ рдЖрд╡рдВрдЯрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ []byte
рджреНрд╡рд╛рд░рд╛ рд╕рдВрджрд░реНрднрд┐рдд рдХрд┐рдпрд╛ []byte
, рдЬрд┐рд╕рдореЗрдВ рдирдИ рд▓рд╛рдЗрди рдХреА рд╕рд╛рдордЧреНрд░реА рд▓рд┐рдЦреА рдЬрд╛рддреА рд╣реИ, рдФрд░ рдЙрд╕рдХреЗ рдмрд╛рдж рд╣реА []byte
рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдЬрд┐рд╕ рдореЗрдореЛрд░реА рдХреЛ рдЗрд╕реЗ рд╕рдВрджрд░реНрднрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЙрд╕реЗ stringStruct
рдореЗрдВ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдЬреЛ рд▓реЛрдЧ рдЕрдзрд┐рдХ рд╡рд┐рд╡рд░рдг рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдЙрдирдХреЗ рд▓рд┐рдП rawstringtmp
рдФрд░ rawstring
рдХреЗ рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдЕрдзреНрдпрдпрди рдХрд░рдиреЗ рдХрд╛ рд╕реБрдЭрд╛рд╡ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред
unsafe
рдкреИрдХреЗрдЬ рдХреЗ рдЕрдВрдзреЗрд░реЗ рдкрдХреНрд╖ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рд╣рдо рд▓рдЧрднрдЧ рд╕рдорд╛рди рд░реВрдк рд╕реЗ рдХреНрд░реИрдВрдХ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
func concat2(x, y string) string { length := len(x) + len(y) if length == 0 { return "" } b := make([]byte, length) copy(b, x) copy(b[len(x):], y) return goString(&b[0], length) }
рд╣рдо []byte
рд╣рд╛рдЗрд▓рд╛рдЗрдЯ рдХрд░рддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣рдо рдПрдХ рдирдИ рд▓рд╛рдЗрди рдХреА рд╕рд╛рдордЧреНрд░реА рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░рддреЗ рд╣реИрдВред рддрдм рд╣рдо рдХреЗрд╡рд▓ рдЕрдкреЗрдХреНрд╖рд┐рдд рд░рдирдЯрд╛рдЗрдо рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХреЛ рд▓рд╛рдХрд░ рд▓рд╛рдЗрди рдХреЛ рдЕрдВрддрд┐рдо рд░реВрдк рджреЗ рд╕рдХрддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рд▓рд┐рдП goString
рдлрд╝рдВрдХреНрд╢рди рдЬрд┐рдореНрдореЗрджрд╛рд░ рд╣реИ:
func goString(ptr *byte, length int) string { s := stringStruct{str: ptr, len: length} return *(*string)(unsafe.Pointer(&s)) }
рдкреНрд░рджрд░реНрд╢рди рд░реЗрдЯрд┐рдВрдЧ: 91.9% (+10.9)ред
AMD64 рд╕рдВрд╕реНрдХрд░рдг
рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдкрд┐рдЫрд▓реЗ рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдЦрд╛рд▓реА рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рд╕рд╛рде рд╕рдВрдЧрддрд┐ рдХреЗ рд▓рд┐рдП рдЕрдиреБрдХреВрд▓рди рдирд╣реАрдВ рд╣реИ, рдФрд░ рд╣рдо рд╕реАрдзреЗ рдореЗрдореЛрд░реА рдЖрд╡рдВрдЯрд┐рдд рдХрд░рдиреЗ рдореЗрдВ рдЕрд╕рдорд░реНрдерддрд╛ рдХреЗ рдХрд╛рд░рдг рдХрдИ рдЕрдирд╛рд╡рд╢реНрдпрдХ рдЧрдгрдирд╛ рднреА рдХрд░рддреЗ рд╣реИрдВ, рд╣рдореЗрдВ рдмрд╛рдЗрдЯ рд╕реНрд▓рд╛рдЗрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред
рдЧреЛ рдЕрд╕реЗрдореНрдмрд▓рд░ рдХреА рдПрдХ рджрд┐рд▓рдЪрд╕реНрдк рд╡рд┐рд╢реЗрд╖рддрд╛ рдпрд╣ рд╣реИ рдХрд┐ рдпрд╣ рдЖрдкрдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЧреИрд░-рдирд┐рд░реНрдпрд╛рдд рдпреЛрдЧреНрдп рд░рдирдЯрд╛рдЗрдо рдлрд╝рдВрдХреНрд╢рдиред runtime┬╖mallocgc
рдХреЙрд▓ рдХреЛ рд╣рдо рдЕрд╕реЗрдВрдмрд▓реА рдХреЛрдб рд╕реЗ рднреА рдХреЙрд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рднрд▓реЗ рд╣реА рдпрд╣ runtime
рдкреИрдХреЗрдЬ рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рди рд╣реЛред рд╣рдо рдЗрд╕ рд╕рдВрдкрддреНрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред
рд╣рдо рд╕реНрдЯреИрдХ рдореЗрдореЛрд░реА рд▓рд╛рдЗрдиреЛрдВ рдХреЗ рд╕реНрд╡рд╛рдорд┐рддреНрд╡ рдХреА рднреА рдЬрд╛рдВрдЪ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рддрд░реНрдХреЛрдВ рдореЗрдВ рд╕реЗ рдХрд┐рд╕реА рдПрдХ рдХреА рд╡рд╛рдкрд╕реА рдХреЛ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реБрд░рдХреНрд╖рд┐рдд рдмрдирд╛рддрд╛ рд╣реИред
рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдПрдХ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рддрд░реНрдХреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ concat2("", "123")
ред x
рдПрдХ рдЦрд╛рд▓реА рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╣реИ, рдФрд░ рдпрджрд┐ y
рд╕реНрдЯреИрдХ рдкрд░ рдЖрд╡рдВрдЯрд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рддреЛ рд╣рдо рдЗрд╕реЗ рд╕рдВрдШрдирди рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреЗ рд░реВрдк рдореЗрдВ рд╡рд╛рдкрд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
//; , x y stringStruct. //; CX - y.str. //; SI - y.len. maybe_return_y: //; . MOVQ (TLS), AX //; *g CMPQ CX, (AX) JL return_y //; y_str < g.stack.lo CMPQ CX, 8(AX) JGE return_y //; y_str >= g.stack.hi JMP concatenate //; y , return_y: MOVQ CX, ret+32(FP) //; stringStruct.len MOVQ SI, ret+40(FP) //; stringStruct.str RET
MOVQ (TLS), AX
* рдХреЛ рд░рдЬрд┐рд╕реНрдЯрд░ рдореЗрдВ рд▓реЗ MOVQ (TLS), AX
ред рд╢реВрдиреНрдп рдСрдлрд╕реЗрдЯ рдкрд░ рдкрдврд╝рдиреЗ рд╕реЗ g.stack.lo
рдлрд╝реАрд▓реНрдб g.stack.lo
, рдФрд░ g.stack.hi
8 рд╡реАрдВ рдмрд╛рдЗрдЯ (64-рдмрд┐рдЯ рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рдХреЗ рд▓рд┐рдП) рд╕реЗ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИред
type g struct { stack struct { lo uintptr
concatenate
рд╢рд░реАрд░ рд╕реНрдореГрддрд┐ рдХреЛ рдЖрд╡рдВрдЯрд┐рдд рдХрд░рддрд╛ рд╣реИ, рдЗрд╕реЗ рджреЛрдиреЛрдВ рд░реЗрдЦрд╛рдУрдВ рд╕реЗ рднрд░рддрд╛ рд╣реИ, рдФрд░ рдПрдХ рдирдИ рд░реЗрдЦрд╛ рджреЗрддрд╛ рд╣реИред
рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдкреВрд░реА рд╕реВрдЪреА #include #include TEXT ┬╖Strings(SB), 0, $48-48 NO_LOCAL_POINTERS // . MOVQ x+0(FP), DX MOVQ x+8(FP), DI MOVQ y+16(FP), CX MOVQ y+24(FP), SI TESTQ DI, DI JZ maybe_return_y // x - , y TESTQ SI, SI JZ maybe_return_x // y - , x concatenate: LEAQ (DI)(SI*1), R8 // len(x) + len(y) // . MOVQ R8, 0(SP) MOVQ $0, 8(SP) MOVB $0, 16(SP) CALL runtime┬╖mallocgc(SB) MOVQ 24(SP), AX // MOVQ AX, newstr-8(SP) // x. MOVQ x+0(FP), DX MOVQ x+8(FP), DI MOVQ AX, 0(SP) MOVQ DX, 8(SP) MOVQ DI, 16(SP) CALL runtime┬╖memmove(SB) // y len(x). MOVQ x+8(FP), DI MOVQ y+16(FP), CX MOVQ y+24(FP), SI MOVQ newstr-8(SP), AX LEAQ (AX)(DI*1), BX MOVQ BX, 0(SP) MOVQ CX, 8(SP) MOVQ SI, 16(SP) CALL runtime┬╖memmove(SB) // . MOVQ newstr-8(SP), AX MOVQ x+8(FP), R8 ADDQ y+24(FP), R8 MOVQ AX, ret+32(FP) MOVQ R8, ret+40(FP) RET maybe_return_y: // . MOVQ (TLS), AX // *g CMPQ CX, (AX) JL return_y // y_ptr < stk.lo CMPQ CX, 8(AX) JGE return_y // y_ptr >= stk.hi JMP concatenate // y , return_y: MOVQ CX, ret+32(FP) MOVQ SI, ret+40(FP) RET maybe_return_x: // . MOVQ (TLS), AX // *g CMPQ DX, (AX) JL return_x // x_ptr < stk.lo CMPQ DX, 8(AX) JGE return_x // x_ptr >= stk.hi JMP concatenate // x , return_x: MOVQ DX, ret+32(FP) MOVQ DI, ret+40(FP) RET
рдпрджрд┐ рдЖрдк рдЗрд╕ рдХреЛрдб рдореЗрдВ NO_LOCAL_POINTERS
рдХреА рдкреНрд░рдХреГрддрд┐ рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ, рддреЛ рдЖрдк asm рд╕реЗ рдХреЙрд▓рд┐рдВрдЧ рдЧреЛ рдлрд╝рдВрдХреНрд╢рди рдкрдврд╝ рд╕рдХрддреЗ рд╣реИрдВ ("рдШрд╛рддрдХ рддреНрд░реБрдЯрд┐: рд▓рд╛рдкрддрд╛ рд╕реНрдЯреИрдореНрдкрдореИрдк") ред
рдкреНрд░рджрд░реНрд╢рди рд░реЗрдЯрд┐рдВрдЧ: 100% (+8.6)ред
рдирд┐рд╖реНрдХрд░реНрд╖ рдореЗрдВ
рд╕рднреА рдХреЛрдб рдХреЛ рдХреЙрдиреИрдЯ рдкреИрдХреЗрдЬ рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдХреНрдпрд╛ рджреБрдирд┐рдпрд╛ рдЗрд╕ рддрд░рд╣ рдХреЗ рддреНрд╡рд░рд┐рдд рд╕рдордЭреМрддреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИ? рдХреМрди рдЬрд╛рдирддрд╛ рд╣реИред
рд▓реЗрдЦ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ, CL123256 рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред рдЙрд╕рдХреЗ рдкрд╛рд╕ рдХрдИ рд╡рд┐рдХрд╛рд╕ рдкрде рд╣реИрдВ:
- рдЗрд╕ рдорд╛рдорд▓реЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╡рд┐рдзрддрд╛рдкреВрд░реНрдг рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ рдЬрдм рдХрдВрдкрд╛рдЗрд▓рд░ рдПрдХ рдЕрд╕реНрдерд╛рдпреА рдмрдлрд░ рдЖрд╡рдВрдЯрд┐рдд рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред рдкреНрд░рддреНрдпреЗрдХ рдорд╛рдорд▓реЗ рдХреЗ рд▓рд┐рдП рдХрдо рд╡рд┐рдХрд╛рд╕ рд╣реЛрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рдЕрдзрд┐рдХ рдкреНрд░рдХрд╛рд░ рдХреЗ рд╕рдВрдШрдирди рдХреЛ рдХрд╡рд░ рдХрд░рддрд╛ рд╣реИ рдФрд░ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд░реВрдк рд╕реЗ рдХреЛрдб (рдорд╢реАрди рдФрд░ рдЧреЛ рдХреЛрдб рджреЛрдиреЛрдВ) рдХреЗ рдЖрдХрд╛рд░ рдореЗрдВ рд╡реГрджреНрдзрд┐ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред
- рд╡рд┐рд╢реЗрд╖ рдорд╛рдорд▓реЛрдВ рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХ рд╡рд┐рд╢реЗрд╖рдЬреНрдЮрддрд╛ред рдЕрдзрд┐рдХ рд▓рд╛рдн, рд▓реЗрдХрд┐рди рдЕрдзрд┐рдХ рдорд╢реАрди рдХреЛрдб, рдЕрдиреБрджреЗрд╢ рдХреИрд╢ рдХреЛ рдиреБрдХрд╕рд╛рди рдкрд╣реБрдВрдЪрд╛ рд╕рдХрддрд╛ рд╣реИред
- рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рд╢реЗрд╖ рдорд╛рдорд▓реЗ рдФрд░ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдореЗрдореЛрд╡ рдХреЗ рд▓рд┐рдП, рдорд╢реАрди рдХреЛрдб рдХреЗ рдЯреЛрдВрд╕, рдЗрд╕ рддрд░рд╣ рд╕реЗ рдХреИрд╕реЗ рдЧреНрд▓рд┐рдмрдХ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣рд╛рдБ рдореБрдЦреНрдп рд░реВрдк рд╕реЗ рд╕рдореАрдЪреАрдирддрд╛ рдХреЗ рдкреНрд░рд╢реНрди рдЙрдарддреЗ рд╣реИрдВред
рд╡рд░реНрддрдорд╛рди рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рд╡рд┐рдХрд▓реНрдк рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдХреА рдПрдХ рдЬреЛрдбрд╝реА рдХреЗ рд╕рдорд╡рд╢рд░рдг рдХрд╛ рд╕рдмрд╕реЗ рдЖрдо рдФрд░ рд╕рд░рд▓ рдорд╛рдорд▓рд╛ рддреЗрдЬ рдХрд░рддрд╛ рд╣реИ (arity = 2)ред
рдпрджрд┐ рдЧреЛ рдЗрд╕ рдкрд░рд┐рд╡рд░реНрддрди рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рддреЛ рддреАрд╕рд░реЗ рдкрдХреНрд╖ рдХреЗ рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХреЗ рд░реВрдк рдореЗрдВ рд╕реНрдЯреНрд░рд┐рдВрдЧ рд╕рдВрдЪрд╛рд▓рди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдХреЗ рддреБрд▓рдиреАрдп рддреНрд╡рд░рдг рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдХрдо рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ, рд╕реБрдВрджрд░ рдФрд░ рд╕реБрд░реБрдЪрд┐рдкреВрд░реНрдг, рд▓реЗрдХрд┐рди рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред