From 05526a444c28c4efcf6d846d13da17d990848abd Mon Sep 17 00:00:00 2001 From: tompng Date: Sun, 25 Feb 2024 00:35:06 +0900 Subject: [PATCH] [ruby/prism] Make pm_integer -> Integer faster https://github.com/ruby/prism/commit/47601e7928 --- prism/templates/ext/prism/api_node.c.erb | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/prism/templates/ext/prism/api_node.c.erb b/prism/templates/ext/prism/api_node.c.erb index 301479b3c5..7b3e685a70 100644 --- a/prism/templates/ext/prism/api_node.c.erb +++ b/prism/templates/ext/prism/api_node.c.erb @@ -39,12 +39,21 @@ pm_string_new(const pm_string_t *string, rb_encoding *encoding) { static VALUE pm_integer_new(const pm_integer_t *integer) { - VALUE result = UINT2NUM(integer->head.value); - size_t shift = 0; - - for (const pm_integer_word_t *node = integer->head.next; node != NULL; node = node->next) { - VALUE receiver = rb_funcall(UINT2NUM(node->value), rb_intern("<<"), 1, ULONG2NUM(++shift * 32)); - result = rb_funcall(receiver, rb_intern("|"), 1, result); + VALUE result; + if (integer->head.next) { + size_t length = integer->length + 1; + VALUE str = rb_str_new(NULL, length * 8); + unsigned char *buf = (unsigned char *)RSTRING_PTR(str); + size_t offset = length * 8; + for (const pm_integer_word_t *node = &integer->head; node != NULL; node = node->next) { + for (int i = 0; i < 8; i++) { + int n = (node->value >> (4 * i)) & 0xf; + buf[--offset] = n < 10 ? n + '0' : n - 10 + 'a'; + } + } + result = rb_funcall(str, rb_intern("to_i"), 1, UINT2NUM(16)); + } else { + result = UINT2NUM(integer->head.value); } if (integer->negative) {