Commit bf38e83
committed
Improve Zstd.decompress performance by avoiding unnecessary memory copy
Currently, `rb_decompress` allocates a temporary buffer and copies the input string using `ALLOC_N` and `memcpy`.
This overhead is significant, especially for large data, and doubles the memory usage during decompression.
## benchmark
```ruby
require 'bundler/inline'
gemfile do
source 'https://rubygems.org'
gem 'zstd-ruby'
gem 'benchmark-ips'
end
require 'securerandom'
large_data = SecureRandom.random_bytes(1024 * 1024 * 100)
compressed_data = Zstd.compress(large_data)
Benchmark.ips do |x|
x.time = 15
x.report("zstd decompress") do
Zstd.decompress(compressed_data)
end
end
```
## before
```
$ ruby zstd.rb
ruby 3.4.8 (2025-12-17 revision 995b59f666) +PRISM [x86_64-linux]
Warming up --------------------------------------
zstd decompress 1.000 i/100ms
Calculating -------------------------------------
zstd decompress 11.148 (± 9.0%) i/s (89.70 ms/i) - 167.000 in 15.085672s
```
## after
```
$ ruby zstd.rb
ruby 3.4.8 (2025-12-17 revision 995b59f666) +PRISM [x86_64-linux]
Warming up --------------------------------------
zstd decompress 2.000 i/100ms
Calculating -------------------------------------
zstd decompress 20.890 (± 9.6%) i/s (47.87 ms/i) - 312.000 in 15.015814s
```1 parent f5aa756 commit bf38e83
1 file changed
+1
-6
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
78 | 78 | | |
79 | 79 | | |
80 | 80 | | |
81 | | - | |
82 | | - | |
83 | | - | |
| 81 | + | |
84 | 82 | | |
85 | 83 | | |
86 | 84 | | |
| |||
107 | 105 | | |
108 | 106 | | |
109 | 107 | | |
110 | | - | |
111 | 108 | | |
112 | 109 | | |
113 | 110 | | |
114 | 111 | | |
115 | 112 | | |
116 | 113 | | |
117 | | - | |
118 | 114 | | |
119 | 115 | | |
120 | 116 | | |
121 | 117 | | |
122 | 118 | | |
123 | 119 | | |
124 | 120 | | |
125 | | - | |
126 | 121 | | |
127 | 122 | | |
128 | 123 | | |
| |||
0 commit comments