Skip to content
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

perf(ivy): improve styling performance #33326

Closed
wants to merge 2 commits into from

Conversation

mhevery
Copy link
Contributor

@mhevery mhevery commented Oct 22, 2019

change the existing implementation from using

string.split(/\s+/);

to a char scan which performers the same thing.

The reason why split(/\s+/) is slow is that:

  • /\s+/ allocates new RegExp every time this code executes.
  • RegExp scans are a lot more expensive because they are more powerful.

change the existing implementation from using

```
string.split(/\s+/);
```

to a char scan which performers the same thing.

The reason why `split(/\s+/)` is slow is that:
- `/\s+/` allocates new `RegExp` every time this code executes.
- `RegExp` scans are a lot more expensive because they are more powerful.
@mhevery mhevery requested a review from a team as a code owner October 22, 2019 17:59
@mhevery mhevery requested a review from matsko October 22, 2019 17:59
@ngbot ngbot bot added this to the needsTriage milestone Oct 22, 2019
@gkalpak
Copy link
Member

gkalpak commented Oct 22, 2019

Wow, I am quite surprised the VM does not optimize the RegExp literal and creates a new RegExp each time. Are you saying that const re = /\s+/; ... newValues.split(re) makes a difference in performance?

Also, ooc, have you tried / +/ (instead of /\s+/)?

matsko
matsko previously requested changes Oct 22, 2019
packages/core/src/render3/util/styling_utils.ts Outdated Show resolved Hide resolved
@mhevery
Copy link
Contributor Author

mhevery commented Oct 22, 2019

Wow, I am quite surprised the VM does not optimize the RegExp literal and creates a new RegExp each time. Are you saying that const re = /\s+/; ... newValues.split(re) makes a difference in performance?

  1. RegExp have internal state so you can't share them.
  2. I think the issue is not that we are allocating RegExp but rather that RegExp is smart, and hence it is not as fast on simples cases as hand tuned. code.

@pkozlowski-opensource
Copy link
Member

I've run benchmarks on this PR and here are the results. Before:

  [class]=" '1' ": 291.984 us(-43%)
  [class]=" '1 2' ": 428.390 us(-109%)
  [class]=" '1 2 3 4 5 6 7 8 9 0' ": 1698.592 us(-729%)
  class="A B" [class]=" '1' ": 329.344 us(-61%)
  class="A B" [class]=" '1 2 3 4 5 6 7 8 9 0' ": 1998.899 us(-876%)
  class="A B" [class]=" '1' " [class.foo]="exp": 389.557 us(-90%)
  class="A B" [class]=" '1 2 3 4 5 6 7 8 9 0' " [class.foo]="exp": 2088.971 us(-920%)
  [element.class]="exp": 204.865 us(0%)

After:

  [class]=" '1' ": 264.108 us(-29%)
  [class]=" '1 2' ": 399.907 us(-95%)
  [class]=" '1 2 3 4 5 6 7 8 9 0' ": 1674.186 us(-717%)
  class="A B" [class]=" '1' ": 299.102 us(-46%)
  class="A B" [class]=" '1 2 3 4 5 6 7 8 9 0' ": 1944.948 us(-849%)
  class="A B" [class]=" '1' " [class.foo]="exp": 354.644 us(-73%)
  class="A B" [class]=" '1 2 3 4 5 6 7 8 9 0' " [class.foo]="exp": 2003.856 us(-878%)
  [element.class]="exp": 204.905 us(0%)

so there is a clear improvement here (although I was expecting it to be higher, TBH). Those numbers are confirmed by checking the results under profiler. Before:

before

After:

after

One can see that split disappeared but splitOnWhitespace isn't "free". Sadly, the need for split is at the very hart of the algorithm so I'm not sure we can do much about it.

Copy link
Member

@pkozlowski-opensource pkozlowski-opensource left a comment

Choose a reason for hiding this comment

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

LGTM. I think we should merge it.
@mhevery I will let you decide on if the perf improvement to the additional code makes it worthwhile.

@mhevery mhevery added action: merge The PR is ready for merge by the caretaker target: major This PR is targeted for the next major release labels Oct 23, 2019
@mhevery mhevery dismissed matsko’s stale review October 23, 2019 20:27

All concerns addressed.

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Nov 23, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker cla: yes target: major This PR is targeted for the next major release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants