Feature #15331 » 0001-Hash-code-memoization-for-short-fstrings-v4.patch
| benchmark/freeze_unique_strings.yml | ||
|---|---|---|
|
prelude: |
|
||
|
str = +"1000000"
|
||
|
benchmark:
|
||
|
freeze_unique_strings: |
|
||
|
str.succ!
|
||
|
-str
|
||
|
loop_count: 1000000 # freeze this many unique strings
|
||
| benchmark/hash_aref_fstr.rb | ||
|---|---|---|
|
h = {}
|
||
|
strs = ('a'..'z').to_a.map!(&:-@)
|
||
|
strs.each { |s| h[s] = s }
|
||
|
200_000.times { strs.each { |s| h[s] } }
|
||
| benchmark/hash_aref_long_str.rb | ||
|---|---|---|
|
h = {}
|
||
|
strs = ['a' * 100] * 10
|
||
|
strs.each { |s| h[s] = s }
|
||
|
200_000.times { strs.each { |s| h[s] } }
|
||
| string.c | ||
|---|---|---|
|
RBASIC(str)->flags |= (tmp_n) << RSTRING_EMBED_LEN_SHIFT;\
|
||
|
} while (0)
|
||
|
#define MEMO_HASH_LEN_MAX ((int) (sizeof(RSTRING(0)->as) - sizeof(st_index_t) - 1))
|
||
|
struct memoized_hash_embeded_str {
|
||
|
char ary[MEMO_HASH_LEN_MAX + 1];
|
||
|
st_index_t memoized_hash;
|
||
|
};
|
||
|
STATIC_ASSERT(memoized_hash_type_punning, sizeof(struct memoized_hash_embeded_str) == sizeof(RSTRING(0)->as));
|
||
|
#define SET_HASH_MEMO(str, hash) do { \
|
||
|
struct RString *rstr = RSTRING(str);\
|
||
|
((struct memoized_hash_embeded_str*) &rstr->as)->memoized_hash = hash;\
|
||
|
} while (0)
|
||
|
#define GET_HASH_MEMO(str) (((struct memoized_hash_embeded_str*) &RSTRING(str)->as)->memoized_hash)
|
||
|
#define CAN_MEMO_HASH(str) \
|
||
|
(RB_FL_TEST_RAW((str), RSTRING_NOEMBED | RUBY_FL_FREEZE) == RUBY_FL_FREEZE && RSTRING_EMBED_LEN(str) <= MEMO_HASH_LEN_MAX)
|
||
|
#define STR_SET_LEN(str, n) do { \
|
||
|
if (STR_EMBED_P(str)) {\
|
||
|
STR_SET_EMBED_LEN((str), (n));\
|
||
| ... | ... | |
|
str = str_new_frozen(rb_cString, str);
|
||
|
}
|
||
|
}
|
||
|
if (CAN_MEMO_HASH(str)) {
|
||
|
SET_HASH_MEMO(str, rb_str_hash(str));
|
||
|
}
|
||
|
RBASIC(str)->flags |= RSTRING_FSTR;
|
||
|
*key = *value = *fstr = str;
|
||
| ... | ... | |
|
st_index_t
|
||
|
rb_str_hash(VALUE str)
|
||
|
{
|
||
|
int e = ENCODING_GET(str);
|
||
|
int e;
|
||
|
if (FL_TEST(str, RSTRING_FSTR) && CAN_MEMO_HASH(str)) {
|
||
|
return GET_HASH_MEMO(str);
|
||
|
}
|
||
|
e = ENCODING_GET(str);
|
||
|
if (e && rb_enc_str_coderange(str) == ENC_CODERANGE_7BIT) {
|
||
|
e = 0;
|
||
|
}
|
||