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_accessorprovided language construct (as well as
attr_writer) vs. defining them yourself (as in
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
@valueattribute in each:
class TestClassAttrAccessor attr_accessor :value def initialize value @value = value end end class TestClassDefMethod def initialize value @value = value end def
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
A commonly used method from the
#has_key?which tells you if the
Hashin question contains a particular key. Rambling Trie’s underlying data structure is an n-ary tree backed by a
Hashwhere each key is the letter corresponding to a child and each value is the
Nodethat 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
nilinstead of calling
#has_key?lowered the time it took…
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…
January 23, 2017
It’s been a while since I last wrote anything about Rambling Trie (or anything at all really), but I wanted to take the time to talk about all the changes and performance improvements that I’ve made to the gem lately and that culminated in the release of version 1.0.0.
The changes worth highlighting are:
NEW: Ability to dump and load tries from disk
It takes a relatively long time to load all the words from a large dictionary into a new trie in memory. This becomes especially annoying when you have to do this full process every time you restart your application, even though you know that the trie is going to remain constant over time.
To sort this out, you can now use the
Rambling::Trie.dumpmethods! Like this:
April 12, 2016
I started writing about Page Objects earlier this month, and as soon as you start talking about Page Objects, you need to have an opinion about where to put your assertions. Do you ask the page if it is in the state it expects to be or do you ask the page for values and assert that they are what you expect them to be in the test?
If you look at FluentLenium and Simplelenium on GitHub, you’ll notice that their corresponding
READMEs describe the usage of the Page Object pattern. Now, if you take a closer look, you’ll also notice that they have an opinion: they’ve included the assertions in the definition of such Page Objects.
Now, my first experience with Page Objects was actually under these conditions. The Page Objects were the main driver…
April 12, 2016
When writing the Unit Testing ActiveRecord eager-loading blog post a couple months ago, I noticed that the test failures I was getting while writing were not very helpful. Initially, I had an assertion that looked like this:
$ rspec spec/controllers/restaurant_controller_spec.rb Failures: 1) RestaurantsController#index eager loads Failure/Error: expect(restaurant.association(:reviews)).to be_loaded expected `#<ActiveRecord::Associations::HasManyAssociation (...) >.loaded?` to return…
April 10, 2016
If you’ve written acceptance tests for web applications in the past (also called feature tests), you might be familiar with tools like Capybara, Simplelenium and FluentLenium. These are great abstractions over the browser (thanks, Selenium!) that provide very nice APIs for testing web applications.
If you’ve done this for a while, you might also have heard of Page Objects. The idea behind them is that your tests should be about the behavior of your application and not about the underlying HTML, since the HTML is an implementation detail and probably not the interesting part of your tests.
Our base acceptance test
Let’s assume that we are working on an application where you can browse and review restaurants and we have an acceptance test…
January 27, 2016
If you’ve worked with relational databases and any ORMs like Java’s Hibernate, .NET’s NHibernate or Rails’
ActiveRecordin the past, you might be familiar with SELECT N+1 issues. It is a common performance problem in database-dependent applications and, because of this, these ORMs provide a built-in solution to this problem.
eager_loadcome to the rescue. Therefore, it is not unusual to find these keywords scattered in different places where your application accesses the database. Hopefully this isn’t a lot of places though - you are using Query Objects, right?
An example application
Let’s imagine for a second that we have an application where you can browse restaurants, which in turn have many reviews…
January 26, 2016
If you have worked with Ruby on Rails before then you might be familiar with ActiveRecord
scopes. Using them, you can achieve what many would consider very readable code. Let’s say that we have an application where we display an inbox where users receive messages.
class Message < ActiveRecord::Base end
Now, let’s imagine that after reading a
Message, it is marked as read, and let’s represent that with a
readcolumn in the database. Additionally, our users can either archive the
Messageor move it to the trash. We’ll represent this concept with a
locationcolumn in the
Querying the database the Rails way
Let’s say that our users want to have a way to view unread messages in their inbox. Using
ActiveRecord, you could achieve…
January 11, 2016
If you’re like me, you like to have control over the plugins that you have installed in your editor setup. However, staying up to date with the different plugins can be a little bit of a hassle from time to time, so lately, I’ve been using YADR, a set of community maintained dotfiles.
A great autocompletion plugin that YADR comes with is neocomplete.vim, which “provides a keyword completion system by maintaining a cache of keywords in the current buffer”. Unfortunately, for it to work, it needs MacVim with Lua enabled.
Now, I already had MacVim installed through Caskroom:
which mvim # /usr/local/bin/mvim ls -l $(which mvim) # /usr/local/bin/mvim -> /opt/homebrew-cask/Caskroom/macvim/7.4-84/mvim
But this version was installed without Lua…