Skip to content

Various micro optimizations #379

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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