Micro Benchmark fastest threadsave Accessor

While working on my new Fast-Gettext i needed a really fast way load the current translations, since they are needed every time, and must be stored inside Thread.current for Thread-safety. So i came up with a small micro benchmark for fastest accessor.

This test is separate into single-access and generic access (just one value / n values)

Results

Ruby 1.8.7
generic:
  Symbol: 1.06s
  String concat: 1.73s
  String add: 1.69s
  String insert: 1.47s
single:
  Symbol: 0.67s
  String: 0.96s

So as we can see, stick to symbols!

Test

require 'benchmark'
BASELINE = 0
def test
  result = Benchmark.measure {1_000_000.times{ yield }}
  result.to_s.strip.split(' ').first.to_f - BASELINE
end

BASELINE = (test{})
Thread.current[:library_name]={}
other = "x"

puts "generic:"
puts "Symbol: #{test{Thread.current[:library_name][:just_a_symbol]}}s"
puts "String concat: #{test{Thread.current["xxxxxx"<<other.to_s]}}s"
puts "String add: #{test{Thread.current["xxxxxx"+other.to_s]}}s"
puts "String insert: #{test{Thread.current["xxxxxx#{other}"]}}s"

puts "single:"
puts "Symbol: #{test{Thread.current[:long_unique_symbol]}}s"
puts "String: #{test{Thread.current["xxxxxx"]}}s"

Whats your Namespace-Fooptrint?

Could it be that you pollute the global namespace ?

If you ask your users to ‘include’ your library this can happen easily!

Calculate footprint

initial = methods.count + Module.constants.count
require 'my_library'
include MyLibrary

puts "Namespace-Footprint"
puts methods.count + Module.constants.count - initial

How to clean up ?

A simple solution is adding a separate Inclusion module, that does not live in your main
namespace and redirect all methods you want to share with the user from your main namespace.

#my_library/inclusion.rb
module MyLibrary
  module Inclusion
    ...
  end
end

#my_library.rb
module MyLibrary
  ..
  Inclusion.public_instance_methods.each do |method|
    define_method method do |*args|
      Inclusion.send(method,*args)
    end
  end
end

Helpful Error Messages in-direct from your App

Custom error pages directly from your app are far better than hand-made pages or those that rails gives you by default. But if they use your controllers/helpers they may send a user into a crash-loop (arriving on /500 and boom-> /500…)

So simple add an errors controller, build some templates(name is e500, since” def 500″ will not work), set them to page caching and ping them after each deploy.

#routes.rb as lat rule
  %w[500 404 422].each do |error|
    map.connect error, :controller=>'errors', :action=>"e#{error}"
  end

#errors_controller.rb
class ErrorsController < ActionController::Base
  helper :all
  layout 'blank' #new layout, without dynamic gimmicks
  caches_page 'e500', 'e404', 'e422'

  #no authentification, so just nil
  def current_user
    nil
  end
  helper_method :current_user
end

#e500.html.erb
<h1>BOOM!</h1>

#deploy.rb
task :ping_error_pages do
  %w[500 404 422].each do |error|
    run "wget -O /dev/null localhost/#{error} --quiet"
  end
end

after "deploy:restart", *%w(
  rs:ping_error_pages
  ...
)

Simple Meta Tags with MetaOnRails

Simple meta tag rules (from google webmaster tools):

  1. do not add useless meta tags
  2. add site-wide-unique meta tags
  3. add max 10 keywords
  4. in doubt add no meta tags, search engines will grab something

Obey or be penalized.

For simplicity use: MetaOnRails Rails plugin

Usage

#in your head (no not that head...)
=display_meta

#in your views, add unique keywords/description that matter
set_meta(
  :keywords=> [@movie.category, @movie.genre,@user.name]*' ',
  :description=>@movie.description
)

Output

<meta name="description" content="my description" />
<meta name="keywords" content="my,keyword" />

Upgrading Ruby from 1.8.6 to 1.8.7 from Source

UPDATE: Just use RVM or install ruby-enterprise-edition, thats far easier …

Just writing this because it took a lot of time to find a working tutorial
Ubuntu Hardy(8.04) has 1.8.6 installed, and Ibex(8.10) already comes with 1.8.7.

sudo apt-get install build-essential libssl-dev libreadline5-dev zlib1g-dev
wget ftp://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7-p72.tar.gz
tar zxvf ruby-1.8.7-*
cd ruby-1.8.7-*
./configure --prefix=/usr/local --with-openssl-dir=/usr --with-readline-dir=/usr --with-zlib-dir=/usr
make
sudo make install

Hope it helps but so far did not work out for me, when using /usr/bin/local/ruby xxx.rb rubygems are not found, and when installed using –prefix=/usr , openssl is broken, since it is the 1.8.6 version and not even manually installing ruby-1.8.7 openssl seemed to work…