Skip to content

Conversation

@schneems
Copy link
Collaborator

@schneems schneems commented Nov 11, 2021

Several PRs aimed at increasing performance.

Main: 0.160596 0.004052 0.164648 ( 0.165109)
This branch: 0.113262 0.002467 0.115729 ( 0.115816)

There are several places where lex items are looped through. This commit
moves them all into one single loop so we only iterate over every element
once instead of N times. (N=3)
There are several places where we call `String#lines` on the
source code. Instead of splitting the same source multiple times
we can split it once and pass that array in via dependency
injection.
Before:  0.140603   0.003740   0.144343 (  0.145287)
After:   0.128684   0.003244   0.131928 (  0.132673)

Before:

![](https://www.dropbox.com/s/smiyw7imd1319a3/Screen%20Shot%202021-11-10%20at%208.48.14%20PM.png?raw=1)

After:

![](https://www.dropbox.com/s/23sswxyol7s9yli/Screen%20Shot%202021-11-10%20at%208.51.53%20PM.png?raw=1)

Calling `String#split` allocates many objects, we are already stripping the string to see if it is empty, we can use this same info to determine the indentation count.
Related to ruby/ruby#5093

Instead of building a bunch of objects then converting them into arrays, we can natively use the objects.

Total allocated: 25407256 bytes (261284 objects)
Total retained:  1937110 bytes (30266 objects)

allocated memory by location
-----------------------------------
  10045332  <internal:kernel>:90
   5273752  Documents/projects/dead_end/lib/dead_end/code_frontier.rb:131
   2267256  Documents/projects/dead_end/lib/dead_end.rb:65
    986760  .rubies/ruby-3.0.2/lib/ruby/3.0.0/ripper/lexer.rb:189
    938301  .rubies/ruby-3.0.2/lib/ruby/3.0.0/ripper/lexer.rb:132
    734800  Documents/projects/dead_end/lib/dead_end/lex_all.rb:24
    668000  .rubies/ruby-3.0.2/lib/ruby/3.0.0/ripper/lexer.rb:97    <== HERE
    471980  Documents/projects/dead_end/lib/dead_end.rb:97
    334040  .rubies/ruby-3.0.2/lib/ruby/3.0.0/ripper/lexer.rb:58
    334040  .rubies/ruby-3.0.2/lib/ruby/3.0.0/ripper/lexer.rb:72

After

Total allocated: 19648672 bytes (252933 objects)
Total retained:  1944374 bytes (30266 objects)

allocated memory by location
-----------------------------------
  10045332  <internal:kernel>:90
   5273752  Documents/projects/dead_end/lib/dead_end/code_frontier.rb:131
   2267256  Documents/projects/dead_end/lib/dead_end.rb:65
    986760  .rubies/ruby-3.0.2/lib/ruby/3.0.0/ripper/lexer.rb:189
    938301  .rubies/ruby-3.0.2/lib/ruby/3.0.0/ripper/lexer.rb:132
    734800  Documents/projects/dead_end/lib/dead_end/lex_all.rb:26

    471980  Documents/projects/dead_end/lib/dead_end.rb:97
    334040  .rubies/ruby-3.0.2/lib/ruby/3.0.0/ripper/lexer.rb:58
    334040  .rubies/ruby-3.0.2/lib/ruby/3.0.0/ripper/lexer.rb:72
    329051  Documents/projects/dead_end/lib/dead_end/code_line.rb:31
    218144  Documents/projects/dead_end/lib/dead_end/code_line.rb:30
@schneems schneems force-pushed the schneems/minor-perfs branch from 7056c55 to d2d992b Compare November 11, 2021 15:17
@schneems
Copy link
Collaborator Author

There's an opportunity to remove the allocations of LexValue and instead use the raw Lexer::Elem objects. It looks like it's a ~7% perf bump for my test case but it will make the project less ergonomic as we depend on those methods in quite a few places. I might consider that move in the future.

@schneems schneems merged commit 48d36cd into main Nov 11, 2021
@schneems schneems deleted the schneems/minor-perfs branch November 11, 2021 15:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants