Boosting Opal's performance with inline JavaScript

"How does it perform?" has been a popular question with Ruby for many years, and Opal, the Ruby to JavaScript compiler, is no exception.

When experimenting with Opal a couple of months ago, I threw together a microbenchmark on top of everyone's favourite recursive factorial and fibonacci algorithms using Benchmark.js in an attempt to answer this question.

Comparison

A few runs on my laptop quickly demonstrated a performance loss of (on average) two orders of magnitude for the Opal/Ruby implementations.

Factorial

Opal#factorial x 270,439 ops/sec ±8.06% (93 runs sampled)

JS#factorial x 23,964,240 ops/sec ±1.28% (94 runs sampled)

Fibonacci

Opal#fibonacci x 10,020 ops/sec ±2.78% (89 runs sampled)

JS#fibonacci x 434,727 ops/sec ±10.29% (80 runs sampled)

Here's the code I used:

Inlining JavaScript

Ruby's backtick operator (or the equivalent %x), which normally calls out to the shell, has no practical use in a browser. Opal reuses it to inline JavaScript in an eminently readable fashion.

The inlined JavaScript implementations of the previous examples look like so:

Lets take a look at what this does to our benchmarks.

RubyWithInlineJS#factorial x 24,201,484 ops/sec ±1.22% (94 runs sampled)

RubyWithInlineJS#fibonacci x 524,180 ops/sec ±1.13% (91 runs sampled)

Woot! That's practically identical to the pure JavaScript implementations.

Conclusion

A neat, inline, JavaScript implementation of an expensive Ruby function or method brings us right back up to the performance of the pure JavaScript verison. In fact, on some runs the inline Opal implementation outperformed the pure JavaScript implementation by a tiny margin.

If you want to run these benchmarks yourself, take a look at the Performance Benchmarks section of the Redson README.

Sidu is a Partner at C42 Engineering. If you liked this post, please consider...

/

Creating Custom ListViews in Android using RubyMotion

While working on a Android app in RubyMotion I wanted to create a layout that is a list of editable key-value pairs like this

list_view.png

Android already has a view to display items in a list called ListView. By default, a ListView can store a collection of values and displays those values in a TextView, which the user cannot edit. So, the list of key-value pairs will have to use a custom implementation.

The default ListView uses an Adapter to store and manage the values in the list. The Adapter in turn contains a collection of items and implements a method called getView. The getView method returns a View for the nth item in the Adapter's collection.

Overriding the getView method in custom Adapter is pretty much the trick to creating a custom ListView.

So, for the custom implementation, the KeyValueAdapter will be a subclass of the BaseAdapter and will override the default getView method. The KeyValueAdapter will also contain an array of key-value pairs that stores the keys and values. Why not a hash of key-value pairs? Because the Adapter needs a to fetch the key-value pairs by index in the getView method.

The KeyValueAdapter will look like this

The source code for the layout is uploaded here.

 

Shishir is an engineer at C42 Engineering. If you liked this post, please consider...

/

Hand Rolling attr_accessor In Ruby

Ruby is a dynamic language that allows us to do great things at runtime. Today, we are going to see how we can use metaprogramming to add methods to an object after it has been created.

Let us create a method my_attr_accessor which mimics Ruby's built in attr_accessor. attr_accessor is used to dynamically create getters and setters for the fields of a class.

We will need to define my_attr_accessor in - please pay attention, this may be confusing - the class Class as an instance method. This makes my_attr_accessor available in all classes as a class methed.

It does nothing at the moment, so we expect NoMethodError to be thrown if we try to use the getter and setter for max_speed.

To be able to run the specs that are present in each of the file snippets below, please make sure that you have rspec gem installed. To run, use the command rspec <filename>.rb

To create a getter and a setter, we are going to use ruby's Object#define_method. This method allows us to add a method definition dynamically, at runtime, to our object.

Now that we have the method definitions in place, we will need to add the actual implementation for accessing and modifying each of the attributes in order to get the specs to pass. For this, we seek the help of Object#instance_variable_get and Object#instance_variable_set.

Object#instance_variable_get allows us to access the instance variables by just sending a string-name of the variable as an argument to it.

Object#instance_variable_set allows us to modify the existing value of the instance variable by sending a string-name of the variable and the value to which it has to be modified.

And there you have it. A hand-rolled implementation of attr_accessor.

Vineeth is an engineer at C42 Engineering. If you liked this post, please consider...

/

Hack of the Week - Vagrant & Chef-Zero

Chef cookbooks quickly get complicated as with deployment strategies change over time. You may waste weeks of your time getting things right. One way to reduce this overhead is to start with a simple one machine build using Vagrant and Chef-Zero to provision it, then move to a multi-machine build and evolve accordingly. As Captain Picard said, we don't jump directly to warp speed, we start with an impulse then engage to warp drive.

Automating DevOps can be time consuming in the short term, but it is essential that it be done properly to sustain continuous delivery on a project. Provisioning machines and making sure that provisioning is idempotent is one of the more time consuming activities involved in setting up automation.

Vagrant and Chef-Zero are two of the tools we use daily to automate the setup of deployment environments. Working with these tools reduces our time by a big factor because of their local runtime and cookbooks caching on developer machine, so no unnecessary network latency while provisioning. We spend majority of time in writing cookbook recipes, as cookbook development cycle is reduced three simple steps write a recipe, provision virtual machine and check if changes are applied to virtual machine. Initial step this simplified development cycle requires developer input in writing cookbook recipes whereas second is automated with vagrant (which requires either chef-solo or chef-zero to converge chef recipes); and third can be automated using test-kitchen (an integration tool for developing and testing infrastructure code).

Previous to chef-zero announcement we used chef-solo to provision virtual machines. Chef-Zero in addition chef-solo features includes improvements such as in-memory and fast-start Chef server intended for development purposes. Although Chef Team have no immediate plans to deprecate chef-solo, they will eventually remove it from Chef. A good reason which made us to shift from chef-solo to chef-zero. (source From Solo to Zero)

To leverage the true power of chef-zero a compatible vagrant configuration is needed. We use following Vagrant configuration as our template.

This Vagrant configuration requires a some vagrant plugins to be pre-installed.

  • vagrant-chef-zero
  • vagrant-berkshelf
  • vagrant-hostmanager

We use Berkshelf to manage our cookbook dependencies. Using Berkshelf gives us a project-like structure to our cookbook.

Conclusion

It's hard to conclude an infrastructure recipe, as software changes so does infrastructure. Starting with a smaller local build then evolving to complex remote build requires a lot of changes made to cookbooks. Before you converge these cookbooks to remote machine, provision a local virtual machine using Vagrant and Chef-Zero to ensure their correctness. Remember, all big things have small beginnings.

Ranjeet is an engineer at C42 Engineering. If you liked this post, please consider...

/

Garden City Ruby Conf - 2015

Here is our deck from the Garden City Ruby Conf 2015 Closing Keynote.

/