Commit 67f30185 authored by Jaroslav Sevcik's avatar Jaroslav Sevcik Committed by Commit Bot

[builtins] Shortcut for empty substrings.

There is no fast path for 0-length substrings, which implied runtime
calls for some of the trickier types of strings (such as non-flat
cons-strings). This made for a big performance gap between
String.p.slice and String.p.substring for those inputs.

This CL just adds the 0-length shortcut in CSA implementation
of SubString.

Here is an example where it makes difference:

  let s = "abcdefghijkalmnopqrst";
  let a = "";

  console.time("Substring");
  for (let i = 0; i < 100000; i++) {
    s += "0";
    a += s.substring(0, 0);
  }
  console.timeEnd("Substring");

Before this change:
> console.timeEnd: Substring, 640.308000

After this change:
> console.timeEnd: Substring, 13.242000

For completeness, here is the time for slice:
> console.timeEnd: Slice, 13.142000

This also recovers performance in the jsdom library, as
observed in https://github.com/jsdom/jsdom/issues/2350.

Bug: v8:6730
Change-Id: I7d2127e4506a86ec2a7ed378293476c3699dc47a
Reviewed-on: https://chromium-review.googlesource.com/c/1365282
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58071}
parent 84b9e927
......@@ -6775,12 +6775,12 @@ TNode<String> CodeStubAssembler::SubString(TNode<String> string,
&original_string_or_invalid_length);
// A real substring (substr_length < string_length).
Label empty(this);
GotoIf(IntPtrEqual(substr_length, IntPtrConstant(0)), &empty);
Label single_char(this);
GotoIf(IntPtrEqual(substr_length, IntPtrConstant(1)), &single_char);
// TODO(jgruber): Add an additional case for substring of length == 0?
// Deal with different string types: update the index if necessary
// and extract the underlying string.
......@@ -6855,6 +6855,12 @@ TNode<String> CodeStubAssembler::SubString(TNode<String> string,
Goto(&end);
}
BIND(&empty);
{
var_result = EmptyStringConstant();
Goto(&end);
}
// Substrings of length 1 are generated through CharCodeAt and FromCharCode.
BIND(&single_char);
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment