Skip to content

Commit 68d6648

Browse files
authored
Remove parsing allocs (#55)
* Re-use the channel between runs. * Fix temp slice escaping in findStructuralIndices. Cleanup: Don't send params already in internalParsedJson. ``` benchmark old ns/op new ns/op delta BenchmarkParseSmall/copy-32 1095 753 -31.20% BenchmarkParseSmall/nocopy-32 1014 684 -32.53% BenchmarkParseMedium/copy-32 4359 3981 -8.67% BenchmarkParseMedium/nocopy-32 3672 3203 -12.77% BenchmarkParseLarge/copy-32 57643 56759 -1.53% BenchmarkParseLarge/nocopy-32 47546 45712 -3.86% BenchmarkParseApache_builds/copy-32 140467 131633 -6.29% BenchmarkParseApache_builds/nocopy-32 105274 96613 -8.23% BenchmarkParseCanada/copy-32 11454566 12444019 +8.64% BenchmarkParseCanada/nocopy-32 11440363 12444615 +8.78% BenchmarkParseCitm_catalog/copy-32 1499697 1388706 -7.40% BenchmarkParseCitm_catalog/nocopy-32 1209008 1176916 -2.65% BenchmarkParseGithub_events/copy-32 71298 69322 -2.77% BenchmarkParseGithub_events/nocopy-32 57038 54787 -3.95% BenchmarkParseGsoc_2018/copy-32 1281316 1272766 -0.67% BenchmarkParseGsoc_2018/nocopy-32 1026481 1011825 -1.43% BenchmarkParseInstruments/copy-32 302662 289939 -4.20% BenchmarkParseInstruments/nocopy-32 257394 244188 -5.13% BenchmarkParseMarine_ik/copy-32 12879480 13697518 +6.35% BenchmarkParseMarine_ik/nocopy-32 12551823 13322868 +6.14% BenchmarkParseMesh/copy-32 3825973 4120152 +7.69% BenchmarkParseMesh/nocopy-32 3838699 4116863 +7.25% BenchmarkParseMesh_pretty/copy-32 4310342 4594306 +6.59% BenchmarkParseMesh_pretty/nocopy-32 4290558 4595993 +7.12% BenchmarkParseNumbers/copy-32 741692 863226 +16.39% BenchmarkParseNumbers/nocopy-32 741221 864157 +16.59% BenchmarkParseRandom/copy-32 1044593 1019031 -2.45% BenchmarkParseRandom/nocopy-32 728212 727910 -0.04% BenchmarkParseTwitter/copy-32 604714 595169 -1.58% BenchmarkParseTwitter/nocopy-32 456703 448870 -1.72% BenchmarkParseTwitterEscaped/copy-32 994717 991081 -0.37% BenchmarkParseTwitterEscaped/nocopy-32 865551 865523 -0.00% BenchmarkParseUpdate_center/copy-32 741393 724639 -2.26% BenchmarkParseUpdate_center/nocopy-32 515773 499503 -3.15% BenchmarkJsonParserLarge/nocopy-32 59050 57776 -2.16% BenchmarkParseNumber/Pos/63bit-32 82.6 86.5 +4.68% BenchmarkParseNumber/Neg/63bit-32 84.4 88.7 +5.11% BenchmarkParseNumberFloat-32 61.5 65.8 +6.94% BenchmarkParseAtof64FloatGolang-32 32.4 32.7 +0.96% BenchmarkParseNumberFloatExp-32 70.4 71.9 +2.09% BenchmarkParseNumberBig-32 131 147 +11.73% BenchmarkParseNumberRandomBits-32 140 153 +9.67% BenchmarkParseNumberRandomFloats-32 122 123 +1.15% BenchmarkParseIntGolang/Pos/63bit-32 29.8 29.9 +0.60% BenchmarkParseIntGolang/Neg/63bit-32 30.1 30.4 +1.23% benchmark old MB/s new MB/s speedup BenchmarkParseSmall/copy-32 172.58 250.88 1.45x BenchmarkParseSmall/nocopy-32 186.38 276.26 1.48x BenchmarkParseMedium/copy-32 534.13 584.79 1.09x BenchmarkParseMedium/nocopy-32 634.04 726.72 1.15x BenchmarkParseLarge/copy-32 487.78 495.38 1.02x BenchmarkParseLarge/nocopy-32 591.36 615.09 1.04x BenchmarkParseApache_builds/copy-32 906.08 966.89 1.07x BenchmarkParseApache_builds/nocopy-32 1208.99 1317.37 1.09x BenchmarkParseCanada/copy-32 196.52 180.89 0.92x BenchmarkParseCanada/nocopy-32 196.76 180.89 0.92x BenchmarkParseCitm_catalog/copy-32 1151.70 1243.75 1.08x BenchmarkParseCitm_catalog/nocopy-32 1428.61 1467.57 1.03x BenchmarkParseGithub_events/copy-32 913.52 939.55 1.03x BenchmarkParseGithub_events/nocopy-32 1141.90 1188.83 1.04x BenchmarkParseGsoc_2018/copy-32 2597.20 2614.64 1.01x BenchmarkParseGsoc_2018/nocopy-32 3241.98 3288.94 1.01x BenchmarkParseInstruments/copy-32 728.03 759.97 1.04x BenchmarkParseInstruments/nocopy-32 856.06 902.36 1.05x BenchmarkParseMarine_ik/copy-32 231.64 217.81 0.94x BenchmarkParseMarine_ik/nocopy-32 237.69 223.94 0.94x BenchmarkParseMesh/copy-32 189.13 175.62 0.93x BenchmarkParseMesh/nocopy-32 188.50 175.76 0.93x BenchmarkParseMesh_pretty/copy-32 365.95 343.33 0.94x BenchmarkParseMesh_pretty/nocopy-32 367.63 343.20 0.93x BenchmarkParseNumbers/copy-32 202.41 173.91 0.86x BenchmarkParseNumbers/nocopy-32 202.54 173.72 0.86x BenchmarkParseRandom/copy-32 488.68 500.94 1.03x BenchmarkParseRandom/nocopy-32 701.00 701.29 1.00x BenchmarkParseTwitter/copy-32 1044.32 1061.07 1.02x BenchmarkParseTwitter/nocopy-32 1382.77 1406.90 1.02x BenchmarkParseTwitterEscaped/copy-32 565.40 567.47 1.00x BenchmarkParseTwitterEscaped/nocopy-32 649.77 649.79 1.00x BenchmarkParseUpdate_center/copy-32 719.16 735.78 1.02x BenchmarkParseUpdate_center/nocopy-32 1033.75 1067.42 1.03x BenchmarkJsonParserLarge/nocopy-32 476.16 486.66 1.02x benchmark old allocs new allocs delta BenchmarkParseSmall/copy-32 11 1 -90.91% BenchmarkParseSmall/nocopy-32 11 1 -90.91% BenchmarkParseMedium/copy-32 11 1 -90.91% BenchmarkParseMedium/nocopy-32 11 1 -90.91% BenchmarkParseLarge/copy-32 16 3 -81.25% BenchmarkParseLarge/nocopy-32 16 3 -81.25% BenchmarkParseApache_builds/copy-32 21 3 -85.71% BenchmarkParseApache_builds/nocopy-32 21 3 -85.71% BenchmarkParseCanada/copy-32 249 3 -98.80% BenchmarkParseCanada/nocopy-32 249 3 -98.80% BenchmarkParseCitm_catalog/copy-32 109 3 -97.25% BenchmarkParseCitm_catalog/nocopy-32 109 3 -97.25% BenchmarkParseGithub_events/copy-32 16 3 -81.25% BenchmarkParseGithub_events/nocopy-32 16 3 -81.25% BenchmarkParseGsoc_2018/copy-32 66 3 -95.45% BenchmarkParseGsoc_2018/nocopy-32 66 3 -95.45% BenchmarkParseInstruments/copy-32 32 3 -90.62% BenchmarkParseInstruments/nocopy-32 32 3 -90.62% BenchmarkParseMarine_ik/copy-32 466 3 -99.36% BenchmarkParseMarine_ik/nocopy-32 466 3 -99.36% BenchmarkParseMesh/copy-32 121 3 -97.52% BenchmarkParseMesh/nocopy-32 121 3 -97.52% BenchmarkParseMesh_pretty/copy-32 121 3 -97.52% BenchmarkParseMesh_pretty/nocopy-32 121 3 -97.52% BenchmarkParseNumbers/copy-32 27 3 -88.89% BenchmarkParseNumbers/nocopy-32 27 3 -88.89% BenchmarkParseRandom/copy-32 75 3 -96.00% BenchmarkParseRandom/nocopy-32 75 3 -96.00% BenchmarkParseTwitter/copy-32 52 3 -94.23% BenchmarkParseTwitter/nocopy-32 52 3 -94.23% BenchmarkParseTwitterEscaped/copy-32 52 3 -94.23% BenchmarkParseTwitterEscaped/nocopy-32 52 3 -94.23% BenchmarkParseUpdate_center/copy-32 57 3 -94.74% BenchmarkParseUpdate_center/nocopy-32 57 3 -94.74% BenchmarkJsonParserLarge/nocopy-32 50 37 -26.00% benchmark old bytes new bytes delta BenchmarkParseSmall/copy-32 664 16 -97.59% BenchmarkParseSmall/nocopy-32 664 16 -97.59% BenchmarkParseMedium/copy-32 664 16 -97.59% BenchmarkParseMedium/nocopy-32 664 16 -97.59% BenchmarkParseLarge/copy-32 796 75 -90.58% BenchmarkParseLarge/nocopy-32 792 71 -91.04% BenchmarkParseApache_builds/copy-32 959 115 -88.01% BenchmarkParseApache_builds/nocopy-32 931 86 -90.76% BenchmarkParseCanada/copy-32 37405 32413 -13.35% BenchmarkParseCanada/nocopy-32 37403 30778 -17.71% BenchmarkParseCitm_catalog/copy-32 6426 3189 -50.37% BenchmarkParseCitm_catalog/nocopy-32 5404 2402 -55.55% BenchmarkParseGithub_events/copy-32 801 81 -89.89% BenchmarkParseGithub_events/nocopy-32 793 73 -90.79% BenchmarkParseGsoc_2018/copy-32 17642 15540 -11.91% BenchmarkParseGsoc_2018/nocopy-32 9844 7733 -21.44% BenchmarkParseInstruments/copy-32 1303 196 -84.96% BenchmarkParseInstruments/nocopy-32 1256 143 -88.61% BenchmarkParseMarine_ik/copy-32 177273 176118 -0.65% BenchmarkParseMarine_ik/nocopy-32 173463 165752 -4.45% BenchmarkParseMesh/copy-32 14516 12118 -16.52% BenchmarkParseMesh/nocopy-32 14545 12117 -16.69% BenchmarkParseMesh_pretty/copy-32 11148 8389 -24.75% BenchmarkParseMesh_pretty/nocopy-32 11088 8421 -24.05% BenchmarkParseNumbers/copy-32 1238 286 -76.90% BenchmarkParseNumbers/nocopy-32 1237 283 -77.12% BenchmarkParseRandom/copy-32 4159 1966 -52.73% BenchmarkParseRandom/nocopy-32 3143 1013 -67.77% BenchmarkParseTwitter/copy-32 2585 973 -62.36% BenchmarkParseTwitter/nocopy-32 2016 420 -79.17% BenchmarkParseTwitterEscaped/copy-32 3005 1424 -52.61% BenchmarkParseTwitterEscaped/nocopy-32 2506 918 -63.37% BenchmarkParseUpdate_center/copy-32 3298 1541 -53.27% BenchmarkParseUpdate_center/nocopy-32 2122 404 -80.96% BenchmarkJsonParserLarge/nocopy-32 1353 633 -53.22% ```
1 parent 2455af9 commit 68d6648

File tree

6 files changed

+102
-54
lines changed

6 files changed

+102
-54
lines changed

benchmarks_test.go

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -58,26 +58,42 @@ func benchmarkFromFile(b *testing.B, filename string) {
5858
}
5959
}
6060
})
61+
b.Run("nocopy-par", func(b *testing.B) {
62+
b.RunParallel(func(pb *testing.PB) {
63+
pj := &ParsedJson{}
64+
b.SetBytes(int64(len(msg)))
65+
b.ReportAllocs()
66+
b.ResetTimer()
67+
for pb.Next() {
68+
// Reset tape
69+
var err error
70+
pj, err = Parse(msg, pj, WithCopyStrings(false))
71+
if err != nil {
72+
b.Fatal(err)
73+
}
74+
}
75+
})
76+
})
6177

6278
}
6379

64-
func BenchmarkSmall(b *testing.B) { benchmarkFromFile(b, "payload-small") }
65-
func BenchmarkMedium(b *testing.B) { benchmarkFromFile(b, "payload-medium") }
66-
func BenchmarkLarge(b *testing.B) { benchmarkFromFile(b, "payload-large") }
67-
func BenchmarkApache_builds(b *testing.B) { benchmarkFromFile(b, "apache_builds") }
68-
func BenchmarkCanada(b *testing.B) { benchmarkFromFile(b, "canada") }
69-
func BenchmarkCitm_catalog(b *testing.B) { benchmarkFromFile(b, "citm_catalog") }
70-
func BenchmarkGithub_events(b *testing.B) { benchmarkFromFile(b, "github_events") }
71-
func BenchmarkGsoc_2018(b *testing.B) { benchmarkFromFile(b, "gsoc-2018") }
72-
func BenchmarkInstruments(b *testing.B) { benchmarkFromFile(b, "instruments") }
73-
func BenchmarkMarine_ik(b *testing.B) { benchmarkFromFile(b, "marine_ik") }
74-
func BenchmarkMesh(b *testing.B) { benchmarkFromFile(b, "mesh") }
75-
func BenchmarkMesh_pretty(b *testing.B) { benchmarkFromFile(b, "mesh.pretty") }
76-
func BenchmarkNumbers(b *testing.B) { benchmarkFromFile(b, "numbers") }
77-
func BenchmarkRandom(b *testing.B) { benchmarkFromFile(b, "random") }
78-
func BenchmarkTwitter(b *testing.B) { benchmarkFromFile(b, "twitter") }
79-
func BenchmarkTwitterEscaped(b *testing.B) { benchmarkFromFile(b, "twitterescaped") }
80-
func BenchmarkUpdate_center(b *testing.B) { benchmarkFromFile(b, "update-center") }
80+
func BenchmarkParseSmall(b *testing.B) { benchmarkFromFile(b, "payload-small") }
81+
func BenchmarkParseMedium(b *testing.B) { benchmarkFromFile(b, "payload-medium") }
82+
func BenchmarkParseLarge(b *testing.B) { benchmarkFromFile(b, "payload-large") }
83+
func BenchmarkParseApache_builds(b *testing.B) { benchmarkFromFile(b, "apache_builds") }
84+
func BenchmarkParseCanada(b *testing.B) { benchmarkFromFile(b, "canada") }
85+
func BenchmarkParseCitm_catalog(b *testing.B) { benchmarkFromFile(b, "citm_catalog") }
86+
func BenchmarkParseGithub_events(b *testing.B) { benchmarkFromFile(b, "github_events") }
87+
func BenchmarkParseGsoc_2018(b *testing.B) { benchmarkFromFile(b, "gsoc-2018") }
88+
func BenchmarkParseInstruments(b *testing.B) { benchmarkFromFile(b, "instruments") }
89+
func BenchmarkParseMarine_ik(b *testing.B) { benchmarkFromFile(b, "marine_ik") }
90+
func BenchmarkParseMesh(b *testing.B) { benchmarkFromFile(b, "mesh") }
91+
func BenchmarkParseMesh_pretty(b *testing.B) { benchmarkFromFile(b, "mesh.pretty") }
92+
func BenchmarkParseNumbers(b *testing.B) { benchmarkFromFile(b, "numbers") }
93+
func BenchmarkParseRandom(b *testing.B) { benchmarkFromFile(b, "random") }
94+
func BenchmarkParseTwitter(b *testing.B) { benchmarkFromFile(b, "twitter") }
95+
func BenchmarkParseTwitterEscaped(b *testing.B) { benchmarkFromFile(b, "twitterescaped") }
96+
func BenchmarkParseUpdate_center(b *testing.B) { benchmarkFromFile(b, "update-center") }
8197

8298
func benchmarkJsoniter(b *testing.B, filename string) {
8399

parse_json_amd64.go

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import (
2828
func (pj *internalParsedJson) initialize(size int) {
2929
// Estimate the tape size to be about 15% of the length of the JSON message
3030
avgTapeSize := size * 15 / 100
31-
if cap(pj.Tape) < avgTapeSize {
31+
if cap(pj.Tape) <= avgTapeSize {
3232
pj.Tape = make([]uint64, 0, avgTapeSize)
3333
}
3434
pj.Tape = pj.Tape[:0]
@@ -46,6 +46,7 @@ func (pj *internalParsedJson) initialize(size int) {
4646
pj.containingScopeOffset = make([]uint64, 0, maxdepth)
4747
}
4848
pj.containingScopeOffset = pj.containingScopeOffset[:0]
49+
pj.indexesChan = indexChan{}
4950
}
5051

5152
func (pj *internalParsedJson) parseMessage(msg []byte, ndjson bool) (err error) {
@@ -63,7 +64,9 @@ func (pj *internalParsedJson) parseMessage(msg []byte, ndjson bool) (err error)
6364
// Make the capacity of the channel smaller than the number of slots.
6465
// This way the sender will automatically block until the consumer
6566
// has finished the slot it is working on.
66-
pj.indexChans = make(chan indexChan, indexSlots-2)
67+
if pj.indexChans == nil {
68+
pj.indexChans = make(chan indexChan, indexSlots-2)
69+
}
6770
pj.buffersOffset = ^uint64(0)
6871

6972
var errStage1 error
@@ -74,29 +77,43 @@ func (pj *internalParsedJson) parseMessage(msg []byte, ndjson bool) (err error)
7477
wg.Add(1)
7578
go func() {
7679
defer wg.Done()
77-
if !pj.unifiedMachine(pj.Message) {
80+
if !pj.unifiedMachine() {
7881
err = errors.New("Bad parsing while executing stage 2")
79-
// drain the channel until empty
80-
for range pj.indexChans {
82+
// Keep consuming...
83+
for idx := range pj.indexChans {
84+
if idx.index == -1 {
85+
break
86+
}
8187
}
8288
}
8389
}()
84-
if !pj.findStructuralIndices(pj.Message) {
90+
if !pj.findStructuralIndices() {
8591
errStage1 = errors.New("Failed to find all structural indices for stage 1")
8692
}
8793
wg.Wait()
8894
} else {
89-
if !pj.findStructuralIndices(pj.Message) {
95+
if !pj.findStructuralIndices() {
9096
// drain the channel until empty
91-
for range pj.indexChans {
97+
for idx := range pj.indexChans {
98+
if idx.index == -1 {
99+
break
100+
}
92101
}
93102
return errors.New("Failed to find all structural indices for stage 1")
94103
}
95-
if !pj.unifiedMachine(pj.Message) {
104+
if !pj.unifiedMachine() {
96105
// drain the channel until empty
97-
for range pj.indexChans {
106+
for {
107+
select {
108+
case idx := <-pj.indexChans:
109+
if idx.index == -1 {
110+
return errors.New("Bad parsing while executing stage 2")
111+
}
112+
// Already drained.
113+
default:
114+
return errors.New("Bad parsing while executing stage 2")
115+
}
98116
}
99-
return errors.New("Bad parsing while executing stage 2")
100117
}
101118
return nil
102119
}

parse_json_amd64_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,10 +104,11 @@ func BenchmarkNdjsonStage1(b *testing.B) {
104104
b.ReportAllocs()
105105
b.ResetTimer()
106106

107+
pj.Message = ndjson
107108
for i := 0; i < b.N; i++ {
108109
// Create new channel (large enough so we won't block)
109110
pj.indexChans = make(chan indexChan, 128*10240)
110-
pj.findStructuralIndices([]byte(ndjson))
111+
pj.findStructuralIndices()
111112
}
112113
}
113114

stage1_find_marks_amd64.go

Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,9 @@ func jsonMarkup(b byte) bool {
3838
return jsonMarkupTable[b]
3939
}
4040

41-
func (pj *internalParsedJson) findStructuralIndices(buf []byte) bool {
42-
43-
f := find_structural_bits_in_slice
44-
if cpuid.CPU.Has(cpuid.AVX512F) {
45-
f = find_structural_bits_in_slice_avx512
46-
}
47-
41+
func (pj *internalParsedJson) findStructuralIndices() bool {
42+
avx512 := cpuid.CPU.Has(cpuid.AVX512F)
43+
buf := pj.Message
4844
// persistent state across loop
4945
// does the last iteration end with an odd-length sequence of backslashes?
5046
// either 0 or 1, but a 64-bit value
@@ -84,21 +80,36 @@ func (pj *internalParsedJson) findStructuralIndices(buf []byte) bool {
8480
stripped_index = ^uint64(0)
8581
}
8682

87-
processed := f(buf[:len(buf) & ^63], &prev_iter_ends_odd_backslash,
88-
&prev_iter_inside_quote, &error_mask,
89-
&prev_iter_ends_pseudo_pred,
90-
index.indexes, &index.length, &carried, &position, pj.ndjson)
83+
var processed uint64
84+
if avx512 {
85+
processed = find_structural_bits_in_slice_avx512(buf[:len(buf) & ^63], &prev_iter_ends_odd_backslash,
86+
&prev_iter_inside_quote, &error_mask,
87+
&prev_iter_ends_pseudo_pred,
88+
index.indexes, &index.length, &carried, &position, pj.ndjson)
89+
} else {
90+
processed = find_structural_bits_in_slice(buf[:len(buf) & ^63], &prev_iter_ends_odd_backslash,
91+
&prev_iter_inside_quote, &error_mask,
92+
&prev_iter_ends_pseudo_pred,
93+
index.indexes, &index.length, &carried, &position, pj.ndjson)
94+
}
9195

9296
// Check if we have at most a single iteration of 64 bytes left, tag on to previous invocation
9397
if uint64(len(buf))-processed <= 64 {
9498
// Process last 64 bytes in larger buffer (to safeguard against reading beyond the end of the buffer)
9599
paddedBuf := [128]byte{}
96100
copy(paddedBuf[:], buf[processed:])
97101
paddedBytes := uint64(len(buf)) - processed
98-
processed += f(paddedBuf[:paddedBytes], &prev_iter_ends_odd_backslash,
99-
&prev_iter_inside_quote, &error_mask,
100-
&prev_iter_ends_pseudo_pred,
101-
index.indexes, &index.length, &carried, &position, pj.ndjson)
102+
if avx512 {
103+
processed += find_structural_bits_in_slice_avx512(paddedBuf[:paddedBytes], &prev_iter_ends_odd_backslash,
104+
&prev_iter_inside_quote, &error_mask,
105+
&prev_iter_ends_pseudo_pred,
106+
index.indexes, &index.length, &carried, &position, pj.ndjson)
107+
} else {
108+
processed += find_structural_bits_in_slice(paddedBuf[:paddedBytes], &prev_iter_ends_odd_backslash,
109+
&prev_iter_inside_quote, &error_mask,
110+
&prev_iter_ends_pseudo_pred,
111+
index.indexes, &index.length, &carried, &position, pj.ndjson)
112+
}
102113
}
103114

104115
if index.length == 0 { // No structural chars found, so error out
@@ -130,7 +141,7 @@ func (pj *internalParsedJson) findStructuralIndices(buf []byte) bool {
130141
buf = buf[processed:]
131142
position -= processed
132143
}
133-
close(pj.indexChans)
144+
pj.indexChans <- indexChan{index: -1}
134145

135146
// a valid JSON file cannot have zero structural indexes - we should have found something
136147
return error_mask == 0 && indexTotal > 0

stage1_find_marks_amd64_test.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,14 @@ func TestFindStructuralIndices(t *testing.T) {
144144
pj.indexChans = make(chan indexChan, 16)
145145

146146
// No need to spawn go-routine since the channel is large enough
147-
pj.findStructuralIndices([]byte(demo_json))
147+
pj.Message = []byte(demo_json)
148+
pj.findStructuralIndices()
148149

149150
ipos, pos := 0, ^uint64(0)
150151
for ic := range pj.indexChans {
152+
if ic.index == -1 {
153+
break
154+
}
151155
for j := 0; j < ic.length; j++ {
152156
pos += uint64((*ic.indexes)[j])
153157
result := fmt.Sprintf("%s%s", strings.Repeat(" ", int(pos)), demo_json[pos:])
@@ -171,10 +175,10 @@ func BenchmarkStage1(b *testing.B) {
171175
b.ResetTimer()
172176

173177
pj := internalParsedJson{}
174-
178+
pj.Message = msg
175179
for i := 0; i < b.N; i++ {
176180
// Create new channel (large enough so we won't block)
177181
pj.indexChans = make(chan indexChan, 128)
178-
pj.findStructuralIndices([]byte(msg))
182+
pj.findStructuralIndices()
179183
}
180184
}

stage2_build_tape_amd64.go

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,9 @@ const retAddressArrayConst = 3
3333

3434
func updateChar(pj *internalParsedJson, idx_in uint64) (done bool, idx uint64) {
3535
if pj.indexesChan.index >= pj.indexesChan.length {
36-
var ok bool
37-
pj.indexesChan, ok = <-pj.indexChans // Get next element from channel
38-
if !ok {
39-
done = true // return done if channel closed
36+
pj.indexesChan = <-pj.indexChans // Get next element from channel
37+
done = pj.indexesChan.index == -1
38+
if done {
4039
return
4140
}
4241
}
@@ -158,8 +157,8 @@ func isValidNullAtom(buf []byte) bool {
158157
return false
159158
}
160159

161-
func (pj *internalParsedJson) unifiedMachine(buf []byte) bool {
162-
160+
func (pj *internalParsedJson) unifiedMachine() bool {
161+
buf := pj.Message
163162
const addOneForRoot = 1
164163

165164
done := false

0 commit comments

Comments
 (0)