You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follow-up to Shopify/ruby-lsp#1849.
This feature utilizes ruby/prism#3478 to implement Shopify/ruby-lsp#1849.
By using ruby/prism#3478, this feature enables performance improvements by reusing Prism's parsed results
instead of parsing the source code. Below is a sample code snippet, which is expected to improve performance by
1.3x in this case.
```ruby
#!/usr/local/bin/ruby
require 'benchmark/ips'
require 'prism'
require 'rubocop-ast'
@source = File.read(__FILE__)
@parse_lex_result = Prism.parse_lex(@source)
def build_processed_source(parse_lex_result)
RuboCop::AST::ProcessedSource.new(
@source,
3.4,
__FILE__,
parser_engine: 'parser_prism',
prism_result: parse_lex_result
)
end
Benchmark.ips do |x|
x.report('source') { build_processed_source(nil) }
x.report('Prism::ParseLexResult') { build_processed_source(@parse_lex_result) }
x.compare!
end
```
```console
$ bundle exec ruby reusable_ast.rb
ruby 3.4.2 (2025-02-15 revision d2930f8e7a) +PRISM [x86_64-darwin23]
Warming up --------------------------------------
source 116.000 i/100ms
Prism::ParseLexResult
151.000 i/100ms
Calculating -------------------------------------
source 1.144k (± 8.4%) i/s - 5.684k in 5.018270s
Prism::ParseLexResult
1.460k (± 5.2%) i/s - 7.399k in 5.082102s
Comparison:
Prism::ParseLexResult: 1460.3 i/s
source: 1144.4 i/s - 1.28x slower
```
Achieving 1.3x speedup with such this simple modification is a significant improvement for Ruby LSP and its users.
## Compatibility
By using `parser_class.instance_method(:initialize).parameters.assoc(:key)`,
the implementation checks whether `Prism#initialize` supports the `:parser` keyword.
If it does not, the system falls back to the conventional parsing method.
This ensures backward compatibility with previous versions of Prism.
## Development Notes
Since this feature is specifically designed for Prism, the keyword name `prism_result` is meant for Prism.
While it may be possible to achieve similar functionality with the Parser gem, there are currently no concrete use cases.
Therefore, for clarity, we have chosen `prism_result` as the keyword.
Additionally, Prism has two types of results: `Prism::ParseResult` and `Prism::ParseLexResult`,
but the `prism_result` keyword argument is meant to receive `Prism::ParseLexResult`.
Since `prism_parse_lex_result` would be too long, the name `prism_result` was chosen to align with the superclass `Prism::Result`.
0 commit comments