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

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions