From 8d635c63276f2c3fc014f5f196602c06b784b4cc Mon Sep 17 00:00:00 2001 From: SpringMT Date: Fri, 24 May 2024 15:24:18 +0900 Subject: [PATCH 1/2] feat: reduce string allocation for decompression --- ext/zstdruby/zstdruby.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/ext/zstdruby/zstdruby.c b/ext/zstdruby/zstdruby.c index 512aa7b..645db71 100644 --- a/ext/zstdruby/zstdruby.c +++ b/ext/zstdruby/zstdruby.c @@ -88,23 +88,22 @@ static VALUE rb_compress_using_dict(int argc, VALUE *argv, VALUE self) static VALUE decompress_buffered(ZSTD_DCtx* dctx, const char* input_data, size_t input_size) { ZSTD_inBuffer input = { input_data, input_size, 0 }; - VALUE result = rb_str_new(0, 0); - + size_t const buffOutSize = ZSTD_DStreamOutSize(); + VALUE output_string = rb_str_buf_new(buffOutSize); + ZSTD_outBuffer output = { RSTRING_PTR(output_string), buffOutSize, 0 }; while (input.pos < input.size) { - ZSTD_outBuffer output = { NULL, 0, 0 }; - output.size += ZSTD_DStreamOutSize(); - VALUE output_string = rb_str_new(NULL, output.size); - output.dst = RSTRING_PTR(output_string); - size_t ret = zstd_stream_decompress(dctx, &output, &input, false); if (ZSTD_isError(ret)) { ZSTD_freeDCtx(dctx); rb_raise(rb_eRuntimeError, "%s: %s", "ZSTD_decompressStream failed", ZSTD_getErrorName(ret)); } - rb_str_cat(result, output.dst, output.pos); + rb_str_modify_expand(output_string, buffOutSize); + output.dst = RSTRING_PTR(output_string) + output.size; + output.size += buffOutSize; } + rb_str_set_len(output_string, output.pos); ZSTD_freeDCtx(dctx); - return result; + return output_string; } static VALUE rb_decompress(int argc, VALUE *argv, VALUE self) From 4377656b0039647f757958229833e6fe67921f72 Mon Sep 17 00:00:00 2001 From: SpringMT Date: Fri, 24 May 2024 16:41:11 +0900 Subject: [PATCH 2/2] fix: SEGV --- ext/zstdruby/zstdruby.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ext/zstdruby/zstdruby.c b/ext/zstdruby/zstdruby.c index 645db71..90c9469 100644 --- a/ext/zstdruby/zstdruby.c +++ b/ext/zstdruby/zstdruby.c @@ -98,8 +98,7 @@ static VALUE decompress_buffered(ZSTD_DCtx* dctx, const char* input_data, size_t rb_raise(rb_eRuntimeError, "%s: %s", "ZSTD_decompressStream failed", ZSTD_getErrorName(ret)); } rb_str_modify_expand(output_string, buffOutSize); - output.dst = RSTRING_PTR(output_string) + output.size; - output.size += buffOutSize; + output.dst = output.dst + output.size; } rb_str_set_len(output_string, output.pos); ZSTD_freeDCtx(dctx);