Skip to content

Commit d2ab928

Browse files
authored
performance(stdlib): Use zlib-rs for much faster zlib decoding/encoding (#1301)
* performance(stdlib): Use zlib-rs for much faster zlib decoding/encoding * chore(stdlib): Make zlib and gzip tests backend independent * chore(stdlib): Changelog for switching to zlib-rs
1 parent 3010fb5 commit d2ab928

File tree

6 files changed

+38
-23
lines changed

6 files changed

+38
-23
lines changed

Cargo.lock

Lines changed: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ data-encoding = { version = "2", optional = true }
146146
digest = { version = "0.10", optional = true }
147147
dyn-clone = { version = "1", default-features = false, optional = true }
148148
exitcode = { version = "1", optional = true }
149-
flate2 = { version = "1", default-features = false, features = ["default"], optional = true }
149+
flate2 = { version = "1.1", default-features = false, features = ["zlib-rs"], optional = true }
150150
hex = { version = "0.4", optional = true }
151151
hmac = { version = "0.12", optional = true }
152152
iana-time-zone = { version = "0.1", optional = true }

LICENSE-3rdparty.csv

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ lalrpop-util,https://github.com/lalrpop/lalrpop,Apache-2.0 OR MIT,Niko Matsakis
135135
lazy_static,https://github.com/rust-lang-nursery/lazy-static.rs,MIT OR Apache-2.0,Marvin Löbel <[email protected]>
136136
libc,https://github.com/rust-lang/libc,MIT OR Apache-2.0,The Rust Project Developers
137137
libredox,https://gitlab.redox-os.org/redox-os/libredox,MIT,4lDO2 <[email protected]>
138+
libz-rs-sys,https://github.com/trifectatechfoundation/zlib-rs,Zlib,The libz-rs-sys Authors
138139
litemap,https://github.com/unicode-org/icu4x,Unicode-3.0,The ICU4X Project Developers
139140
log,https://github.com/rust-lang/log,MIT OR Apache-2.0,The Rust Project Developers
140141
loom,https://github.com/tokio-rs/loom,MIT,Carl Lerche <[email protected]>
@@ -281,6 +282,7 @@ zerofrom-derive,https://github.com/unicode-org/icu4x,Unicode-3.0,Manish Goregaok
281282
zeroize,https://github.com/RustCrypto/utils/tree/master/zeroize,Apache-2.0 OR MIT,The RustCrypto Project Developers
282283
zerovec,https://github.com/unicode-org/icu4x,Unicode-3.0,The ICU4X Project Developers
283284
zerovec-derive,https://github.com/unicode-org/icu4x,Unicode-3.0,Manish Goregaokar <[email protected]>
285+
zlib-rs,https://github.com/trifectatechfoundation/zlib-rs,Zlib,The zlib-rs Authors
284286
zstd,https://github.com/gyscos/zstd-rs,MIT,Alexandre Bury <[email protected]>
285287
zstd-safe,https://github.com/gyscos/zstd-rs,MIT OR Apache-2.0,Alexandre Bury <[email protected]>
286288
zstd-sys,https://github.com/gyscos/zstd-rs,MIT OR Apache-2.0,Alexandre Bury <[email protected]>

changelog.d/1301.enhancement.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
The `encode_gzip`, `decode_gzip`, `encode_zlib` and `decode_zlib` methods now uses the [zlib-rs](https://github.com/trifectatechfoundation/zlib-rs) backend
2+
which is much faster than the previous backend `miniz_oxide`.
3+
4+
authors: JakubOnderka

src/stdlib/encode_gzip.rs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -115,35 +115,32 @@ impl FunctionExpression for EncodeGzipFn {
115115

116116
#[cfg(test)]
117117
mod test {
118-
use base64::Engine;
119-
120118
use crate::value;
121119

122120
use super::*;
123121

124-
fn decode_base64(text: &str) -> Vec<u8> {
125-
let engine = base64::engine::GeneralPurpose::new(
126-
&base64::alphabet::STANDARD,
127-
base64::engine::general_purpose::GeneralPurposeConfig::new(),
128-
);
129-
130-
engine.decode(text).expect("Cannot decode from Base64")
122+
fn encode(text: &str, level: flate2::Compression) -> Vec<u8> {
123+
let mut encoder = GzEncoder::new(text.as_bytes(), level);
124+
let mut output = vec![];
125+
encoder.read_to_end(&mut output).unwrap();
126+
output
131127
}
132128

133129
test_function![
134130
encode_gzip => EncodeGzip;
135131

136132
with_defaults {
137133
args: func_args![value: value!("you_have_successfully_decoded_me.congratulations.you_are_breathtaking.")],
138-
want: Ok(value!(decode_base64("H4sIAAAAAAAA/w3LgQ3AIAgEwI1ciVD8qqmVRKAJ29cBLjWo8weyEIHZHXMmVYhWVHpRRFfb7DHZhy4reQBv0LXB3p2fsVr5AXeBkepGAAAA").as_bytes())),
134+
want: Ok(value!(encode("you_have_successfully_decoded_me.congratulations.you_are_breathtaking.", flate2::Compression::default()).as_bytes())),
139135
tdef: TypeDef::bytes().infallible(),
140136
}
141137

142138
with_custom_compression_level {
143139
args: func_args![value: value!("you_have_successfully_decoded_me.congratulations.you_are_breathtaking."), compression_level: 9],
144-
want: Ok(value!(decode_base64("H4sIAAAAAAAC/w3LgQ3AIAgEwI1ciVD8qqmVRKAJ29cBLjWo8weyEIHZHXMmVYhWVHpRRFfb7DHZhy4reQBv0LXB3p2fsVr5AXeBkepGAAAA").as_bytes())),
140+
want: Ok(value!(encode("you_have_successfully_decoded_me.congratulations.you_are_breathtaking.", flate2::Compression::new(9)).as_bytes())),
145141
tdef: TypeDef::bytes().infallible(),
146142
}
143+
147144
invalid_constant_compression {
148145
args: func_args![value: value!("test"), compression_level: 11],
149146
want: Err("compression level must be <= 10"),

src/stdlib/encode_zlib.rs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -116,33 +116,29 @@ impl FunctionExpression for EncodeZlibFn {
116116

117117
#[cfg(test)]
118118
mod test {
119-
use base64::Engine;
120-
121119
use crate::value;
122120

123121
use super::*;
124122

125-
fn decode_base64(text: &str) -> Vec<u8> {
126-
let engine = base64::engine::GeneralPurpose::new(
127-
&base64::alphabet::STANDARD,
128-
base64::engine::general_purpose::GeneralPurposeConfig::new(),
129-
);
130-
131-
engine.decode(text).expect("Cannot decode from Base64")
123+
fn encode(text: &str, level: flate2::Compression) -> Vec<u8> {
124+
let mut encoder = ZlibEncoder::new(text.as_bytes(), level);
125+
let mut output = vec![];
126+
encoder.read_to_end(&mut output).unwrap();
127+
output
132128
}
133129

134130
test_function![
135131
encode_zlib => EncodeZlib;
136132

137133
with_defaults {
138134
args: func_args![value: value!("you_have_successfully_decoded_me.congratulations.you_are_breathtaking.")],
139-
want: Ok(value!(decode_base64("eJwNy4ENwCAIBMCNXIlQ/KqplUSgCdvXAS41qPMHshCB2R1zJlWIVlR6UURX2+wx2YcuK3kAb9C1wd6dn7Fa+QH9gRxr").as_bytes())),
135+
want: Ok(value!(encode("you_have_successfully_decoded_me.congratulations.you_are_breathtaking.", flate2::Compression::default()).as_bytes())),
140136
tdef: TypeDef::bytes().infallible(),
141137
}
142138

143139
with_custom_compression_level {
144140
args: func_args![value: value!("you_have_successfully_decoded_me.congratulations.you_are_breathtaking."), compression_level: 9],
145-
want: Ok(value!(decode_base64("eNoNy4ENwCAIBMCNXIlQ/KqplUSgCdvXAS41qPMHshCB2R1zJlWIVlR6UURX2+wx2YcuK3kAb9C1wd6dn7Fa+QH9gRxr").as_bytes())),
141+
want: Ok(value!(encode("you_have_successfully_decoded_me.congratulations.you_are_breathtaking.", flate2::Compression::new(9)).as_bytes())),
146142
tdef: TypeDef::bytes().infallible(),
147143
}
148144

0 commit comments

Comments
 (0)