Skip to content

Commit 911660a

Browse files
committed
Add reusable contexts for performance
1 parent 44ac00f commit 911660a

File tree

7 files changed

+1246
-7
lines changed

7 files changed

+1246
-7
lines changed

README.md

Lines changed: 144 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,66 @@ require 'zstd-ruby'
3838

3939
```ruby
4040
compressed_data = Zstd.compress(data)
41-
compressed_data = Zstd.compress(data, complession_level) # default compression_level is 0
41+
compressed_data = Zstd.compress(data, compression_level) # default compression_level is 3
4242
```
4343

44-
### Compression using Dictionary
44+
### Context-based Compression (Recommended)
45+
46+
For better performance when compressing multiple pieces of data, use reusable contexts:
47+
4548
```ruby
46-
# dictionary is supposed to have been created using `zstd --train`
47-
compressed_using_dict = Zstd.compress_using_dict("", IO.read('dictionary_file'))
49+
# Create a reusable context
50+
ctx = Zstd::Context.new(level: 6)
51+
52+
# Compress multiple pieces of data efficiently
53+
compressed1 = ctx.compress(data1)
54+
compressed2 = ctx.compress(data2)
55+
56+
# Decompress with the same context
57+
original1 = ctx.decompress(compressed1)
58+
original2 = ctx.decompress(compressed2)
59+
```
60+
61+
**Performance Benefits:**
62+
- **2-3x faster** than module methods for repeated operations
63+
- **Memory efficient** - contexts are created once and reused
64+
- **Thread-safe** - each context instance is independent
65+
66+
### Specialized Contexts
67+
68+
For memory optimization in specialized use cases:
69+
70+
```ruby
71+
# Compression-only context (50% memory savings)
72+
cctx = Zstd::CContext.new(level: 6)
73+
compressed = cctx.compress(data)
74+
75+
# Decompression-only context (50% memory savings)
76+
dctx = Zstd::DContext.new
77+
original = dctx.decompress(compressed)
78+
```
79+
80+
### Dictionary Compression
81+
82+
Dictionaries provide better compression for similar data:
83+
84+
```ruby
85+
# Using module methods
86+
dictionary = File.read('dictionary_file')
87+
compressed = Zstd.compress_using_dict(data, dictionary, level)
88+
original = Zstd.decompress_using_dict(compressed, dictionary)
89+
90+
# Using contexts (better performance for repeated operations)
91+
cctx = Zstd::CContext.new(level: 6, dict: dictionary)
92+
dctx = Zstd::DContext.new(dict: dictionary)
93+
94+
compressed = cctx.compress(data)
95+
original = dctx.decompress(compressed)
96+
97+
# Unified context with dictionary
98+
ctx = Zstd::Context.new(level: 6, dict: dictionary)
99+
compressed = ctx.compress(data)
100+
original = ctx.decompress(compressed)
48101
```
49102

50103
### Streaming Compression
@@ -72,7 +125,7 @@ res << stream.finish
72125
data = Zstd.decompress(compressed_data)
73126
```
74127

75-
### Decomporession using Dictionary
128+
### Simple Decompression using Dictionary
76129
```ruby
77130
# dictionary is supposed to have been created using `zstd --train`
78131
Zstd.decompress_using_dict(compressed_using_dict, IO.read('dictionary_file'))
@@ -87,6 +140,92 @@ result << stream.decompress(cstr[0, 10])
87140
result << stream.decompress(cstr[10..-1])
88141
```
89142

143+
## API Reference
144+
145+
### Context Classes
146+
147+
#### `Zstd::Context`
148+
Unified context supporting both compression and decompression with lazy allocation.
149+
150+
```ruby
151+
# Initialize with options
152+
ctx = Zstd::Context.new(level: 6) # Compression level only
153+
ctx = Zstd::Context.new(level: 6, dict: dictionary) # With dictionary
154+
ctx = Zstd::Context.new(6) # Positional argument
155+
ctx = Zstd::Context.new(6, dictionary) # Positional with dictionary
156+
ctx = Zstd::Context.new # Default settings
157+
```
158+
159+
**Methods:**
160+
- `compress(data)` → String - Compress data and return compressed bytes
161+
- `decompress(compressed_data)` → String - Decompress data and return original bytes
162+
163+
#### `Zstd::CContext`
164+
Compression-only context for memory optimization.
165+
166+
```ruby
167+
# Initialize
168+
cctx = Zstd::CContext.new(level: 6) # Compression level only
169+
cctx = Zstd::CContext.new(level: 6, dict: dictionary) # With dictionary
170+
cctx = Zstd::CContext.new(6) # Positional argument
171+
cctx = Zstd::CContext.new(6, dictionary) # Positional with dictionary
172+
```
173+
174+
**Methods:**
175+
- `compress(data)` → String - Compress data and return compressed bytes
176+
177+
#### `Zstd::DContext`
178+
Decompression-only context for memory optimization.
179+
180+
```ruby
181+
# Initialize
182+
dctx = Zstd::DContext.new # Default settings
183+
dctx = Zstd::DContext.new(dict: dictionary) # With dictionary
184+
dctx = Zstd::DContext.new(dictionary) # Positional dictionary
185+
```
186+
187+
**Methods:**
188+
- `decompress(compressed_data)` → String - Decompress data and return original bytes
189+
190+
### Module Methods
191+
192+
#### Compression
193+
- `Zstd.compress(data, level = 3)` → String
194+
- `Zstd.compress_using_dict(data, dictionary, level = 3)` → String
195+
196+
#### Decompression
197+
- `Zstd.decompress(compressed_data)` → String
198+
- `Zstd.decompress_using_dict(compressed_data, dictionary)` → String
199+
200+
#### Utilities
201+
- `Zstd.zstd_version` → Integer - Returns the ZSTD library version
202+
203+
### Performance Guidelines
204+
205+
**When to use each approach:**
206+
207+
| Use Case | Recommended API | Benefits |
208+
|----------|----------------|----------|
209+
| Single operations | `Zstd.compress/decompress` | Simple, no setup |
210+
| Multiple operations | `Zstd::Context` | 2-3x faster, convenient |
211+
| Compression-heavy | `Zstd::CContext` | Faster + 50% memory savings |
212+
| Decompression-heavy | `Zstd::DContext` | 50% memory savings |
213+
| Dictionary workflows | Contexts with `dict:` | Better compression + performance |
214+
215+
**Compression Levels:**
216+
- **1-3**: Fast compression, larger files
217+
- **6 (default)**: Balanced speed/compression
218+
- **9-19**: Better compression, slower speed
219+
- **Negative values**: Ultra-fast mode
220+
221+
## Benchmarks
222+
223+
To test performance on your system:
224+
225+
```bash
226+
cd benchmarks
227+
ruby quick_benchmark.rb # Fast overview of all APIs (recommended)
228+
```
90229

91230
## JRuby
92231
This gem does not support JRuby.

0 commit comments

Comments
 (0)