Skip to content

Commit

Permalink
Merge pull request #379 from Shopify/micro-opt
Browse files Browse the repository at this point in the history
Various micro optimizations
  • Loading branch information
byroot authored Nov 14, 2024
2 parents eb4859d + 6365387 commit a8fe3e4
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 19 deletions.
9 changes: 5 additions & 4 deletions ext/msgpack/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ static inline void _msgpack_buffer_add_new_chunk(msgpack_buffer_t* b)
static inline void _msgpack_buffer_append_reference(msgpack_buffer_t* b, VALUE string)
{
VALUE mapped_string;
if(ENCODING_GET(string) == msgpack_rb_encindex_ascii8bit && RTEST(rb_obj_frozen_p(string))) {
if(ENCODING_GET_INLINED(string) == msgpack_rb_encindex_ascii8bit && RB_OBJ_FROZEN_RAW(string)) {
mapped_string = string;
} else {
mapped_string = rb_str_dup(string);
Expand All @@ -309,8 +309,9 @@ static inline void _msgpack_buffer_append_reference(msgpack_buffer_t* b, VALUE s

_msgpack_buffer_add_new_chunk(b);

char* data = RSTRING_PTR(mapped_string);
size_t length = RSTRING_LEN(mapped_string);
char* data;
size_t length;
RSTRING_GETMEM(mapped_string, data, length);

b->tail.first = (char*) data;
b->tail.last = (char*) data + length;
Expand All @@ -330,7 +331,7 @@ void _msgpack_buffer_append_long_string(msgpack_buffer_t* b, VALUE string)
{
if(b->io != Qnil) {
msgpack_buffer_flush(b);
if (ENCODING_GET(string) == msgpack_rb_encindex_ascii8bit) {
if (ENCODING_GET_INLINED(string) == msgpack_rb_encindex_ascii8bit) {
rb_funcall(b->io, b->io_write_all_method, 1, string);
} else {
msgpack_buffer_append(b, RSTRING_PTR(string), RSTRING_LEN(string));
Expand Down
7 changes: 4 additions & 3 deletions ext/msgpack/buffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,13 +237,14 @@ void _msgpack_buffer_append_long_string(msgpack_buffer_t* b, VALUE string);

static inline size_t msgpack_buffer_append_string(msgpack_buffer_t* b, VALUE string)
{
size_t length = RSTRING_LEN(string);
size_t length;
char *ptr;
RSTRING_GETMEM(string, ptr, length);

if(length > b->write_reference_threshold) {
_msgpack_buffer_append_long_string(b, string);

} else {
msgpack_buffer_append(b, RSTRING_PTR(string), length);
msgpack_buffer_append(b, ptr, length);
}

return length;
Expand Down
7 changes: 4 additions & 3 deletions ext/msgpack/extconf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@
"-fvisibility=hidden",
"-I..",
"-Wall",
"-O3",
"-std=gnu99"
])
append_cflags(RbConfig::CONFIG["debugflags"]) if RbConfig::CONFIG["debugflags"]

append_cflags("-DRUBY_DEBUG=1") if ENV["MSGPACK_DEBUG"]
if ENV["MSGPACK_DEBUG"]
append_cflags(RbConfig::CONFIG["debugflags"]) if RbConfig::CONFIG["debugflags"]
append_cflags("-DRUBY_DEBUG=1")
end

if RUBY_VERSION.start_with?('3.0.') && RUBY_VERSION <= '3.0.5'
# https://bugs.ruby-lang.org/issues/18772
Expand Down
29 changes: 20 additions & 9 deletions ext/msgpack/packer.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@
#define MSGPACK_PACKER_IO_FLUSH_THRESHOLD_TO_WRITE_STRING_BODY (1024)
#endif

#ifndef UNREACHABLE_RETURN
// Ruby 2.5
#define UNREACHABLE_RETURN() return
#endif

struct msgpack_packer_t;
typedef struct msgpack_packer_t msgpack_packer_t;

Expand Down Expand Up @@ -404,27 +409,33 @@ static inline bool msgpack_packer_is_utf8_compat_string(VALUE v, int encindex)
{
return encindex == msgpack_rb_encindex_utf8
|| encindex == msgpack_rb_encindex_usascii
|| (rb_enc_asciicompat(rb_enc_from_index(encindex)) && ENC_CODERANGE_ASCIIONLY(v));
|| ENC_CODERANGE_ASCIIONLY(v);
}

static inline void msgpack_packer_write_string_value(msgpack_packer_t* pk, VALUE v)
{
/* actual return type of RSTRING_LEN is long */
unsigned long len = RSTRING_LEN(v);
if(len > 0xffffffffUL) {
// TODO rb_eArgError?
rb_raise(rb_eArgError, "size of string is too long to pack: %lu bytes should be <= %lu", len, 0xffffffffUL);
long len = RSTRING_LEN(v);

if(RB_UNLIKELY(len > 0xffffffffL)) {
rb_raise(rb_eArgError, "size of string is too long to pack: %lu bytes should be <= %ld", len, 0xffffffffL);
UNREACHABLE_RETURN();
}

if (RB_UNLIKELY(pk->compatibility_mode)) {
msgpack_packer_write_raw_header(pk, (unsigned int)len);
msgpack_buffer_append_string(PACKER_BUFFER_(pk), v);
return;
}

int encindex = ENCODING_GET(v);
if(msgpack_packer_is_binary(v, encindex) && !pk->compatibility_mode) {
int encindex = ENCODING_GET_INLINED(v);
if(msgpack_packer_is_binary(v, encindex)) {
/* write ASCII-8BIT string using Binary type */
msgpack_packer_write_bin_header(pk, (unsigned int)len);
msgpack_buffer_append_string(PACKER_BUFFER_(pk), v);
} else {
/* write UTF-8, US-ASCII, or 7bit-safe ascii-compatible string using String type directly */
/* in compatibility mode, packer packs String values as is */
if(!pk->compatibility_mode && !msgpack_packer_is_utf8_compat_string(v, encindex)) {
if(RB_UNLIKELY(!msgpack_packer_is_utf8_compat_string(v, encindex))) {
/* transcode other strings to UTF-8 and write using String type */
VALUE enc = rb_enc_from_encoding(rb_utf8_encoding()); /* rb_enc_from_encoding_index is not extern */
v = rb_str_encode(v, enc, 0, Qnil);
Expand Down

0 comments on commit a8fe3e4

Please sign in to comment.