-
Notifications
You must be signed in to change notification settings - Fork 199
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
Performance issues on large inputs #918
Comments
Do you have non-ASCII characters in your Ruby code? I guess that's the reason why If you have only ASCII characters then it's safe to assume that any part of your input (i.e. any range/sub-string) is also valid. However it's not true for multibyte encodings like UTF-8. Lexer operates on bytes, and so when it constructs a token it uses byte offsets to define its location. This arbitrary range can be invalid, for example for a byte string [char1_byte1, char1_byte2, char2_byte1, char2_byte2] it's valid to use ranges Could you please check if it also happens if you have only ASCII characters in your input? |
Ok, that's actually explains it a bit. Basically: code_raw = File.read(path);
puts Benchmark.measure { Parser::CurrentRuby.parse(code_raw) }
code_ascii = code_raw.encode('ASCII', 'UTF-8', undef: :replace);
puts Benchmark.measure { Parser::CurrentRuby.parse(code_ascii) } Giving:
Which is a 2x improvement. And indeed it completely changes the flamegraph: So my problem actually split in 2:
|
FWIW, there was supposedly a significant performance decrease between 3.0.2.0 and 3.0.3.2. I don't interface with See this open issue from over a year ago: glebm/i18n-tasks#407
When I downgraded |
This method probably could be optimised by a lot according to your benchmark profile (and IIRC this loop has been added in At first you could try removing the loop locally to see if improves performance and if so feel free to send a PR. |
The commit (547d731) says it was introduced in v3.0.3.0: A quadratic loop to detect duplicate keys is the likely root cause. Rails translation files can have thousands of keys in the same hash. |
- Replaces O(n^2) processing loop with a set. I benchmarked parsing a file with a single 5000 key hash to test this change's performance. Before: **Before** ```sh $ hyperfine --warmup 3 'bin/ruby-parse hash_bench.rb' Benchmark 1: bin/ruby-parse hash_bench.rb Time (mean ± σ): 2.678 s ± 0.029 s [User: 2.613 s, System: 0.061 s] Range (min … max): 2.636 s … 2.738 s 10 runs ``` **After** ```sh $ hyperfine --warmup 3 'bin/ruby-parse hash_bench.rb' Benchmark 1: bin/ruby-parse hash_bench.rb Time (mean ± σ): 421.3 ms ± 4.1 ms [User: 366.9 ms, System: 49.9 ms] Range (min … max): 414.8 ms … 426.1 ms 10 runs ``` - Closes whitequark#918
- Replaces O(n^2) processing loop with a set. I benchmarked parsing a file with a single 5000 key hash to test this change's performance. Before: **Before** ```sh $ hyperfine --warmup 3 'bin/ruby-parse hash_bench.rb' Benchmark 1: bin/ruby-parse hash_bench.rb Time (mean ± σ): 2.678 s ± 0.029 s [User: 2.613 s, System: 0.061 s] Range (min … max): 2.636 s … 2.738 s 10 runs ``` **After** ```sh $ hyperfine --warmup 3 'bin/ruby-parse hash_bench.rb' Benchmark 1: bin/ruby-parse hash_bench.rb Time (mean ± σ): 421.3 ms ± 4.1 ms [User: 366.9 ms, System: 49.9 ms] Range (min … max): 414.8 ms … 426.1 ms 10 runs ``` - See whitequark#918
This is the first version which includes the fix (whitequark/parser#924) to a performance issue (whitequark/parser#918) first introduced in 3.0.3.0 (whitequark/parser@547d731) Fixes #407
This is the first version which includes the fix (whitequark/parser#924) to a performance issue (whitequark/parser#918) first introduced in 3.0.3.0 (whitequark/parser@547d731) Fixes #407
Noticed that parsing time has a worse than linear dependency on the input size. To illustrate it, I've generated a few files including ruby hashes growing in size in constant steps.
Results:
Profiling shows that we're spending most of the time in lexer's
advance
function which in turn spends 2/3 of it's time inBuffer#slice
which in turn callsString#encode
function.Unfortunately I have no good ideas on how to solve the performance issue. It looks like fixing it could bring substantial speedup to a number of projects including widely popular
rubocop
. WDYT?The text was updated successfully, but these errors were encountered: