Skip to content

Commit 34fd5db

Browse files
Bryan C. Millsbradfitz
Bryan C. Mills
authored andcommitted
archive/zip: replace RWMutex with sync.Map
This change replaces the compressors and decompressors maps with instances of sync.Map, eliminating the need for Mutex locking in NewReader and NewWriter. The impact for encoding large payloads is miniscule, but as the payload size decreases, the reduction in setup costs becomes measurable. updates #17973 updates #18177 name old time/op new time/op delta CompressedZipGarbage 13.6ms ± 3% 13.8ms ± 4% ~ (p=0.275 n=14+16) CompressedZipGarbage-6 2.81ms ±10% 2.80ms ± 9% ~ (p=0.616 n=16+16) CompressedZipGarbage-48 606µs ± 4% 600µs ± 3% ~ (p=0.110 n=16+15) Zip64Test 88.7ms ± 5% 87.5ms ± 5% ~ (p=0.150 n=14+14) Zip64Test-6 88.6ms ± 8% 94.5ms ±13% ~ (p=0.070 n=14+16) Zip64Test-48 102ms ±19% 101ms ±19% ~ (p=0.599 n=16+15) Zip64TestSizes/4096 21.7µs ±10% 23.0µs ± 2% ~ (p=0.076 n=14+12) Zip64TestSizes/4096-6 7.58µs ±13% 7.49µs ±18% ~ (p=0.752 n=16+16) Zip64TestSizes/4096-48 19.5µs ± 8% 18.0µs ± 4% -7.74% (p=0.000 n=16+15) Zip64TestSizes/1048576 1.36ms ± 9% 1.40ms ± 8% +2.79% (p=0.029 n=24+25) Zip64TestSizes/1048576-6 262µs ±11% 260µs ±10% ~ (p=0.506 n=24+24) Zip64TestSizes/1048576-48 120µs ± 7% 116µs ± 7% -3.05% (p=0.006 n=24+25) Zip64TestSizes/67108864 86.8ms ± 6% 85.1ms ± 5% ~ (p=0.149 n=14+17) Zip64TestSizes/67108864-6 15.9ms ± 2% 16.1ms ± 6% ~ (p=0.279 n=14+17) Zip64TestSizes/67108864-48 4.51ms ± 5% 4.53ms ± 4% ~ (p=0.766 n=15+17) name old alloc/op new alloc/op delta CompressedZipGarbage 5.63kB ± 0% 5.63kB ± 0% ~ (all equal) CompressedZipGarbage-6 15.4kB ± 0% 15.4kB ± 0% ~ (all equal) CompressedZipGarbage-48 25.5kB ± 3% 25.6kB ± 2% ~ (p=0.450 n=16+16) Zip64Test 20.0kB ± 0% 20.0kB ± 0% ~ (p=0.060 n=16+13) Zip64Test-6 20.0kB ± 0% 20.0kB ± 0% ~ (p=0.136 n=16+14) Zip64Test-48 20.0kB ± 0% 20.0kB ± 0% ~ (p=1.000 n=16+16) Zip64TestSizes/4096 20.0kB ± 0% 20.0kB ± 0% ~ (all equal) Zip64TestSizes/4096-6 20.0kB ± 0% 20.0kB ± 0% ~ (all equal) Zip64TestSizes/4096-48 20.0kB ± 0% 20.0kB ± 0% -0.00% (p=0.002 n=16+13) Zip64TestSizes/1048576 20.0kB ± 0% 20.0kB ± 0% ~ (all equal) Zip64TestSizes/1048576-6 20.0kB ± 0% 20.0kB ± 0% ~ (all equal) Zip64TestSizes/1048576-48 20.1kB ± 0% 20.1kB ± 0% ~ (p=0.775 n=24+25) Zip64TestSizes/67108864 20.0kB ± 0% 20.0kB ± 0% ~ (all equal) Zip64TestSizes/67108864-6 20.0kB ± 0% 20.0kB ± 0% ~ (p=0.272 n=16+17) Zip64TestSizes/67108864-48 20.1kB ± 0% 20.1kB ± 0% ~ (p=0.098 n=14+15) name old allocs/op new allocs/op delta CompressedZipGarbage 44.0 ± 0% 44.0 ± 0% ~ (all equal) CompressedZipGarbage-6 44.0 ± 0% 44.0 ± 0% ~ (all equal) CompressedZipGarbage-48 44.0 ± 0% 44.0 ± 0% ~ (all equal) Zip64Test 53.0 ± 0% 53.0 ± 0% ~ (all equal) Zip64Test-6 53.0 ± 0% 53.0 ± 0% ~ (all equal) Zip64Test-48 53.0 ± 0% 53.0 ± 0% ~ (all equal) Zip64TestSizes/4096 53.0 ± 0% 53.0 ± 0% ~ (all equal) Zip64TestSizes/4096-6 53.0 ± 0% 53.0 ± 0% ~ (all equal) Zip64TestSizes/4096-48 53.0 ± 0% 53.0 ± 0% ~ (all equal) Zip64TestSizes/1048576 53.0 ± 0% 53.0 ± 0% ~ (all equal) Zip64TestSizes/1048576-6 53.0 ± 0% 53.0 ± 0% ~ (all equal) Zip64TestSizes/1048576-48 53.0 ± 0% 53.0 ± 0% ~ (all equal) Zip64TestSizes/67108864 53.0 ± 0% 53.0 ± 0% ~ (all equal) Zip64TestSizes/67108864-6 53.0 ± 0% 53.0 ± 0% ~ (all equal) Zip64TestSizes/67108864-48 53.0 ± 0% 53.0 ± 0% ~ (all equal) https://perf.golang.org/search?q=upload:20170428.4 Change-Id: Idb7bec091a210aba833066f8d083d66e27788286 Reviewed-on: https://go-review.googlesource.com/42113 Run-TryBot: Bryan Mills <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]>
1 parent e5c9358 commit 34fd5db

File tree

1 file changed

+21
-26
lines changed

1 file changed

+21
-26
lines changed

src/archive/zip/register.go

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -103,51 +103,46 @@ func (r *pooledFlateReader) Close() error {
103103
}
104104

105105
var (
106-
mu sync.RWMutex // guards compressor and decompressor maps
106+
compressors sync.Map // map[uint16]Compressor
107+
decompressors sync.Map // map[uint16]Decompressor
108+
)
107109

108-
compressors = map[uint16]Compressor{
109-
Store: func(w io.Writer) (io.WriteCloser, error) { return &nopCloser{w}, nil },
110-
Deflate: func(w io.Writer) (io.WriteCloser, error) { return newFlateWriter(w), nil },
111-
}
110+
func init() {
111+
compressors.Store(Store, Compressor(func(w io.Writer) (io.WriteCloser, error) { return &nopCloser{w}, nil }))
112+
compressors.Store(Deflate, Compressor(func(w io.Writer) (io.WriteCloser, error) { return newFlateWriter(w), nil }))
112113

113-
decompressors = map[uint16]Decompressor{
114-
Store: ioutil.NopCloser,
115-
Deflate: newFlateReader,
116-
}
117-
)
114+
decompressors.Store(Store, Decompressor(ioutil.NopCloser))
115+
decompressors.Store(Deflate, Decompressor(newFlateReader))
116+
}
118117

119118
// RegisterDecompressor allows custom decompressors for a specified method ID.
120119
// The common methods Store and Deflate are built in.
121120
func RegisterDecompressor(method uint16, dcomp Decompressor) {
122-
mu.Lock()
123-
defer mu.Unlock()
124-
125-
if _, ok := decompressors[method]; ok {
121+
if _, dup := decompressors.LoadOrStore(method, dcomp); dup {
126122
panic("decompressor already registered")
127123
}
128-
decompressors[method] = dcomp
129124
}
130125

131126
// RegisterCompressor registers custom compressors for a specified method ID.
132127
// The common methods Store and Deflate are built in.
133128
func RegisterCompressor(method uint16, comp Compressor) {
134-
mu.Lock()
135-
defer mu.Unlock()
136-
137-
if _, ok := compressors[method]; ok {
129+
if _, dup := compressors.LoadOrStore(method, comp); dup {
138130
panic("compressor already registered")
139131
}
140-
compressors[method] = comp
141132
}
142133

143134
func compressor(method uint16) Compressor {
144-
mu.RLock()
145-
defer mu.RUnlock()
146-
return compressors[method]
135+
ci, ok := compressors.Load(method)
136+
if !ok {
137+
return nil
138+
}
139+
return ci.(Compressor)
147140
}
148141

149142
func decompressor(method uint16) Decompressor {
150-
mu.RLock()
151-
defer mu.RUnlock()
152-
return decompressors[method]
143+
di, ok := decompressors.Load(method)
144+
if !ok {
145+
return nil
146+
}
147+
return di.(Decompressor)
153148
}

0 commit comments

Comments
 (0)