-
Notifications
You must be signed in to change notification settings - Fork 743
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
Avoid creating a new array of strings simply to be checked against #1141
Conversation
Does this have a marked performance improvement? I believe we only call this method once per lex. |
Not at all. Just reductions in array allocations.
I checked this by running against Jekyll's |
Wait, hang on. Why is this method being called so often? |
Also, we don't really need an array, so if the allocation is really where the problem is (and not that this method is being called upwards of 5000 times for some reason) I'd prefer to just use |
@jneen Because this method is part of two frequently called methods (based on how Jekyll and kramdown is using Rouge): Lines 403 to 406 in df23679
rouge/lib/rouge/guessers/source.rb Lines 13 to 20 in df23679
Indeed, my issue here is to eliminate as much unnecessary allocations (and retained objects) as possible. (Irrespective of whether they have a significant impact on the performance (speed)). To that end using just strings and an operator call is all the more welcome. |
Can you tell me more about that pattern of calling? I want to make sure we're optimizing for the right stuff. |
@jneen Jekyll has a custom Liquid tag that can be used to render code-blocks with syntax-highlighting in a Jekyll site's templates and themes. def render_rouge(code)
require "rouge"
formatter = ::Rouge::Formatters::HTMLLegacy.new(
:line_numbers => @highlight_options[:linenos],
:wrap => false,
:css_class => "highlight",
:gutter_class => "gutter",
:code_class => "code"
)
lexer = ::Rouge::Lexer.find_fancy(@lang, code) || Rouge::Lexers::PlainText
formatter.format(lexer.lex(code))
end This method will be called *for every use of formatter.format(lexer.lex(code)) A similar code exists in kramdown that is used to render fenced code-blocks in Markdown: def self.call(converter, text, lang, type, call_opts)
opts = options(converter, type)
call_opts[:default_lang] = opts[:default_lang]
return nil unless lang || opts[:default_lang] || opts[:guess_lang]
lexer = ::Rouge::Lexer.find_fancy(lang || opts[:default_lang], text)
return nil if opts[:disable] || !lexer || (lexer.tag == "plaintext" && !opts[:guess_lang])
opts[:css_class] ||= 'highlight' # For backward compatibility when using Rouge 2.0
formatter = formatter_class(opts).new(opts)
formatter.format(lexer.lex(text))
end |
Makes sense, thank you! |
Instead, stash the array in a class constant or simply use the double-pipe (
||
) operator.