Skip to content

Faster Sexp#line options #30

@presidentbeef

Description

@presidentbeef

Right now, Sexp#line can be used to either fetch or set the line number. This has led to some bugs which were addressed by ce28448

But Sexp#line is quite a bit slower (relatively) due to the added logic. The method gets called a lot, so it might make sense to have a faster path.

Benchmark code
require 'sexp_processor'
require 'benchmark/ips'

class Sexp
  def set_line x
    @line = x
    self
  end

  def get_line
    @line
  end
end

test_sexp = Sexp.new.line(1)

Benchmark.ips do |x|
  x.report "line" do
    test_sexp.line(10)
  end

  x.report "set_line" do
    test_sexp.set_line(10)
  end

  x.report "line=" do
    test_sexp.line = 10
  end

  x.compare!
end

Benchmark.ips do |x|
  x.report "line" do
    test_sexp.line
  end

  x.report "get_line" do
    test_sexp.get_line
  end

  x.compare!
end
Benchmark results
Warming up --------------------------------------
                line    88.816k i/100ms
            set_line   176.887k i/100ms
               line=   193.423k i/100ms
Calculating -------------------------------------
                line      1.708M (± 3.0%) i/s -      8.615M in   5.047446s
            set_line      6.326M (± 4.3%) i/s -     31.663M in   5.014701s
               line=      7.188M (± 3.2%) i/s -     35.977M in   5.010991s

Comparison:
               line=:  7187710.6 i/s
            set_line:  6326318.9 i/s - 1.14x  slower
                line:  1708412.4 i/s - 4.21x  slower

Warming up --------------------------------------
                line   145.990k i/100ms
            get_line   197.802k i/100ms
Calculating -------------------------------------
                line      3.323M (± 3.3%) i/s -     16.643M in   5.014754s
            get_line      8.896M (± 4.2%) i/s -     44.505M in   5.012103s

Comparison:
            get_line:  8896218.1 i/s
                line:  3322652.5 i/s - 2.68x  slower

I did a rough search-and-replace of calls to Sexp#line in SexpProcessor and RubyParser. The performance difference is maybe 3-5%. So maybe not worth it?

The method names could certainly use work. I like Sexp#with_line to suggest that it is returning self. Sexp#lineno or Sexp#line_no could be used for fetching? Since lines are often copied from existing Sexps, maybe a method like Sexp#copy_line to pass in a Sexp?

Just thoughts, not attached to any of this.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions