Archive for 2018

  • Ruby performance: #attr_accessor vs. method definition

    February 19, 2018

    I’ve been digging a lot into Ruby performance lately and this much digging has taken me into some very interesting corners of Rubyland. My latest surprise has been the difference between defining attribute methods via the attr_accessor provided language construct (as well as attr_reader and attr_writer) vs. defining them yourself (as in def attribute and def attribute=). Here’s what I ran into…

    I created two simple classes with identical interfaces. The only difference between the two is how we are defining access to set and get the @value attribute in each:

    class TestClassAttrAccessor
      attr_accessor :value
    
      def initialize value
        @value = value
      end
    end
    
    class TestClassDefMethod
      def initialize value
        @value = value
      end
    
      def

    Continue Reading →

  • Ruby performance: Hash's #has_key? vs. #[] (square brackets)

    February 15, 2018

    During my time last year developing performance improvements for Rambling Trie, I stumbled into something quite interesting that happens with Ruby’s Hash class.

    A commonly used method from the Hash interface is #has_key? which tells you if the Hash in question contains a particular key. Rambling Trie’s underlying data structure is an n-ary tree backed by a Hash where each key is the letter corresponding to a child and each value is the Node that corresponds to that letter. As you might imagine, #has_key? is a common operation called throughout the gem implementation.

    To my surprise, while running some Ruby benchmarks I noticed that accessing the key with #[] and verifying if it was nil instead of calling #has_key? lowered the time it took…

    Continue Reading →

  • Ruby performance: Using benchmarks and memory_profiler to chase performance degradations

    February 11, 2018

    While working on some of the performance improvements for version 1.0.0 of Rambling Trie late in 2016 and early in 2017, I upgraded from Ruby 2.3.3 to Ruby 2.4.0 imagining that the newer version would help me on my mission to make all operations execute a bit faster. To my surprise, I ran into a significant performance degradation after upgrading - specifically, there was a ~25% increase in the time it took to execute a script using a trie with a big-ish word dictionary. This intrigued me enough that I decided to take a closer look.

    Benchmarking with Ruby

    After some investigation with the help of Ruby’s own Benchmark, I realized that while most operations were a bit slower, the main problem was a lot more visible during intensive operations…

    Continue Reading →