Skip to content

Optimize uint32 hash computation. #1107

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
Jun 1, 2016
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
2 changes: 1 addition & 1 deletion jerry-core/ecma/base/ecma-globals.h
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,7 @@ typedef double ecma_number_t;
/**
* Maximum number of characters in string representation of ecma-uint32
*/
#define ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32 32
#define ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32 10

/**
* Maximum value of valid array index
Expand Down
20 changes: 8 additions & 12 deletions jerry-core/ecma/base/ecma-helpers-conversion.c
Original file line number Diff line number Diff line change
Expand Up @@ -783,29 +783,25 @@ ecma_uint32_to_utf8_string (uint32_t value, /**< value to convert */
lit_utf8_byte_t *out_buffer_p, /**< buffer for string */
lit_utf8_size_t buffer_size) /**< size of buffer */
{
const lit_utf8_byte_t digits[10] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };

lit_utf8_byte_t *p = out_buffer_p + buffer_size - 1;
lit_utf8_size_t bytes_copied = 0;
lit_utf8_byte_t *buf_p = out_buffer_p + buffer_size;

do
{
JERRY_ASSERT (p >= out_buffer_p);
JERRY_ASSERT (buf_p >= out_buffer_p);

*p-- = digits[value % 10];
buf_p--;
*buf_p = (lit_utf8_byte_t) ((value % 10) + LIT_CHAR_0);
value /= 10;

bytes_copied++;
}
while (value != 0);

p++;
JERRY_ASSERT (buf_p >= out_buffer_p);

JERRY_ASSERT (p >= out_buffer_p);
lit_utf8_size_t bytes_copied = (lit_utf8_size_t) (out_buffer_p + buffer_size - buf_p);

if (likely (p != out_buffer_p))
if (likely (buf_p != out_buffer_p))
{
memmove (out_buffer_p, p, bytes_copied);
memmove (out_buffer_p, buf_p, bytes_copied);
}

return bytes_copied;
Expand Down
24 changes: 17 additions & 7 deletions jerry-core/ecma/base/ecma-helpers-string.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,15 +229,25 @@ ecma_new_ecma_string_from_code_unit (ecma_char_t code_unit) /**< code unit */
ecma_string_t *
ecma_new_ecma_string_from_uint32 (uint32_t uint32_number) /**< UInt32-represented ecma-number */
{
ecma_string_t *string_desc_p = ecma_alloc_string ();
string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_UINT32_IN_DESC | ECMA_STRING_REF_ONE;

lit_utf8_byte_t byte_buf[ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32];
lit_utf8_size_t bytes_copied = ecma_uint32_to_utf8_string (uint32_number,
byte_buf,
ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32);
lit_utf8_byte_t *buf_p = byte_buf + ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32;

uint32_t value = uint32_number;
do
{
JERRY_ASSERT (buf_p >= byte_buf);

string_desc_p->hash = lit_utf8_string_calc_hash (byte_buf, bytes_copied);
buf_p--;
*buf_p = (lit_utf8_byte_t) ((value % 10) + LIT_CHAR_0);
value /= 10;
}
while (value != 0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This loop is the same as used in ecma_uint32_to_utf8_string. Wouldn't be better if we made that function always inline?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, because that function is called from several places, and only this one is time critical. The memmove part is also not needed here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only a few. You eliminated one, so 2 call remains after this PR.


lit_utf8_size_t size = (lit_utf8_size_t) (byte_buf + ECMA_MAX_CHARS_IN_STRINGIFIED_UINT32 - buf_p);

ecma_string_t *string_desc_p = ecma_alloc_string ();
string_desc_p->refs_and_container = ECMA_STRING_CONTAINER_UINT32_IN_DESC | ECMA_STRING_REF_ONE;
string_desc_p->hash = lit_utf8_string_calc_hash (buf_p, size);

string_desc_p->u.common_field = 0;
string_desc_p->u.uint32_number = uint32_number;
Expand Down