Twitter in Plain English

January 5th, 2009

Here’s a great introduction to Twitter. You can follow me on Twitter here: http://twitter.com/lojic

Ruby Dynamic Method Invocation Performance

December 22nd, 2008

Ruby is a very flexible and expressive language. A recent question posted by a Ruby newbie got me looking through my IRC logs for a discussion about the performance of various dynamic method invocation approaches, so I thought I’d share some performance results.

Ruby is currently my primary programming language, and I like it a lot; however, the conciseness (except for blocks) and performance of its higher order function capabilities could be improved. Scheme and Haskell beat it in this regard.

Consider three versions of a higher order function, caller, and associated ways of providing information to it to allow invoking a method dynamically given a pre-existing object and argument:

# 1. lambda
def caller fn
  fn.call(obj, arg)
end

caller(lambda {|obj,arg| obj.meth(arg) })

# 2. send
def caller sym
  obj.send(sym, arg)
end

caller(:meth)

# 3. bind/call
def caller meth
  meth.bind(obj).call(arg)
end

caller(MyClass.instance_method(:meth))

A simple benchmark of the three approaches with results follows. The benchmark uses an elide(n) method that has been added to String:

lam = lambda {|s,n| s.elide(n) }
sen = :elide
met = String.instance_method(:elide)

bm(5) do |x|
  x.report('lambda') { 100_000.times { lam.call('abcdef',4) } }
  x.report('send') { 100_000.times { 'abcdef'.send(sen,4) } }
  x.report('meth') { 100_000.times { met.bind('abc').call(4) } }
end

           user     system      total        real
lambda 1.460000   0.510000   1.970000 (  1.982085)
send   0.810000   0.260000   1.070000 (  1.075201)
meth   0.660000   0.250000   0.910000 (  0.913455)

# results with the 3 preparation lines w/in their respective loops

           user     system      total        real
lambda 1.900000   0.590000   2.490000 (  2.498358)
send   0.800000   0.250000   1.050000 (  1.068035)
meth   0.760000   0.260000   1.020000 (  1.021275)

I personally like the lambda approach, but Ruby does impose a penalty for using it.

Blog Bifurcation Completed

November 29th, 2008

I’ve split my blog into two separate blogs. This blog has been repurposed with a more narrow technical / professional focus which will hopefully provide more value for my clients, customers & other software developers.

I’ll be posting other articles (personal, humorous, etc.) to my family blog.

In the process, I’ve become more familiar with nginx, SliceHost.com & WordPress and will likely be sharing about that later.

Astute readers may have noticed that my original plan to create the family blog using some whiz-bang technology was abandoned in favor of good ‘ol WordPress. Hopefully this is only temporary. I’ve been learning Haskell and looking into Clojure, Arc & Qi, so I’d like to be able to demonstrate some cool bleeding edge stuff in the near future.

Regardless of that, I have to say that Haskell is one of the coolest programming languages I’ve encountered. I highly recommend Programming in Haskell. It makes learning Haskell a joy.

Sticking With Linux For Server Deployments

September 8th, 2008

I recently considered switching my server deployments from Linux to FreeBSD. I need to move a number of sites off a dedicated server to either a different dedicated server (less money), or to a vps (much less money). Since I have to go through some pain with switching, I figured now was a good time to try and decide whether I should stick with Linux (Debian/Ubuntu) or move to FreeBSD.

After spending too many hours researching and experimenting (multiple installations of FreeBSD & lots of software built/installed), I’ve decided to stick with Linux for hosting web applications. Here are some advantages for each OS from my perspective.

FreeBSD Advantages

  • A slight performance advantage currently from my research, but this is debatable
  • My primary desktop is Mac OSX which is based on FreeBSD, so I would be able to leverage sysadmin knowledge between my development machine and my hosted machines. This is the same advantage I had when my main development machine was Ubuntu and I hosted apps on Ubuntu. However, OSX doesn’t require much Unix sysadmin knowledge, so this isn’t nearly as important as the analog below.
  • I like the idea of building packages from source, and the ports system does this very nicely.
  • The organization of the OS seems superior to me. The ports system, startup scripts, file locations, etc.
  • Paul Graham’s server OS of choice (at least for news.ycombinator.com), so I expect Arc will continue to be well supported on it (that is if Arc continues itself)
  • Yahoo & other large sites use it.

Linux Advantages

  • Ubuntu is a much better desktop OS, and I’ve decided to use it on my non-Mac home computers, so I can leverage sysadmin knowledge between my home machines and hosted machines. The desktop installation for Ubuntu 8.04 is unbelievably nice. If I ever become dissatisfied with OSX as my primary desktop, I’ll switch back to Ubuntu in a heartbeat. I just loaded Ubuntu 8.04 on my old 900 MHz AMD w/ 384 MB RAM, and it’s quite responsive.
  • I’ve accumulated more sysadmin knowledge for Linux than for FreeBSD, and supporting two operating systems (OSX / Linux) is more appealing than supporting three.
  • Better virtualization support
  • Linux threading seems to perform better (although FreeBSD has caught up a little)
  • Companies such as slicehost.com support Linux, but not FreeBSD (due to virtualization issues), so this limits my options with FreeBSD
  • Auto power management works out of the box - shutdown the OS and the computer powers down
  • The binary package system is much faster for installations. If I need to get another web server up and running quickly, I can do it much easier with Debian/Ubuntu than with FreeBSD.
  • Google & other large sites use it

The two operating systems seem quite close to me, and it’s possible I’ll make a different decision a year or two down the road, but for now, the cost of switching from Linux to FreeBSD is higher than any expected benefit - particularly since my code rests upon Apache, Mongrel, Ruby, Rails, etc.

I have an emotional bias toward BSD since I started out on SunOS (as far as Unix is concerned), and it seems to have a richer history; however, Debian/Ubuntu seems to be the most practical choice for me at this time.

Even though I ended up sticking with my current server platform, I do feel better about having performed my due diligence rather than continuing with a default, and I have some really great notes for setting up a FreeBSD system should I need to do so in the future :)

How to Write a Spelling Corrector in Ruby

September 4th, 2008

Peter Norvig wrote a simple spelling corrector in 20 lines of Python 2.5,
so I thought I’d see what it looks like in Ruby. Here are some areas I’m not pleased with:

  1. List comprehensions in Python made the edits1 function more elegant IMO.
  2. The boolean expression in the correct function evaluates empty sets/arrays as false in Python but not in Ruby, so I had to add the “result.empty? ? nil : result” expression to several functions. I expect there’s a better way to handle this also.

Otherwise, the translation was pretty straightforward.

Here’s a link to Norvig’s page:
http://www.norvig.com/spell-correct.html

That page includes a link to a text file that I saved locally as
holmes.txt: http://www.norvig.com/holmes.txt

def words text
  text.downcase.scan(/[a-z]+/)
end

def train features
  model = Hash.new(1)
  features.each {|f| model[f] += 1 }
  return model
end

NWORDS = train(words(File.new('holmes.txt').read))
LETTERS = ("a".."z").to_a.join

def edits1 word
  n = word.length
  deletion = (0...n).collect {|i| word[0...i]+word[i+1..-1] }
  transposition = (0...n-1).collect {|i| word[0...i]+word[i+1,1]+word[i,1]+word[i+2..-1] }
  alteration = []
  n.times {|i| LETTERS.each_byte {|l| alteration << word[0...i]+l.chr+word[i+1..-1] } }
  insertion = []
  (n+1).times {|i| LETTERS.each_byte {|l| insertion << word[0...i]+l.chr+word[i..-1] } }
  result = deletion + transposition + alteration + insertion
  result.empty? ? nil : result
end

def known_edits2 word
  result = []
  edits1(word).each {|e1| edits1(e1).each {|e2| result << e2 if NWORDS.has_key?(e2) }}
  result.empty? ? nil : result
end

def known words
  result = words.find_all {|w| NWORDS.has_key?(w) }
  result.empty? ? nil : result
end

def correct word
  (known([word]) or known(edits1(word)) or known_edits2(word) or
    [word]).max {|a,b| NWORDS[a] <=> NWORDS[b] }
end

After you’ve saved the holmes.txt file, load the code into irb and call the correct function with a string as follows:

badkins:~/sync/code/ruby$ irb
irb(main):001:0> require 'spelling_corrector.rb'
=> true
irb(main):002:0> correct "whree"
=> "where"

Ubuntu Linux 8.04 - Wake on LAN

September 3rd, 2008

Now that I’ve switched to a Macbook Pro with OSX Leopard as my primary desktop, I’ve located my Ubuntu machine in another part of the house to be accessible to my children. Not wanting to walk to the room where it’s located just to flip the power switch, I researched how to get “wake on LAN” working, so I could power it up remotely.

1. Enable the appropriate setting in your BIOS. Mine had something to do with wake on PCI device.

2. Install ethtool if you don’t already have it.

sudo apt-get install ethtool
cd /etc/init.d
sudo vim wakeonlanconfig

Add the following lines to that file:

#!/bin/bash
ethtool -s eth0 wol g

Install the script:

sudo update-rc.d -f wakeonlanconfig defaults

Run the script:

sudo /etc/init.d/wakeonlanconfig

3. Keep the network interface alive after shut down.

sudo vim /etc/init.d/halt

Change the following line:

halt -d -f -i $poweroff $hddown

to the following line (i.e. remove the -i)

halt -d -f $poweroff $hddown

4. Get the MAC address

ifconfig | grep HW

5. Send the magic packet via the following Ruby program:

require 'socket'
mac_addr = "\x21\x53\x39\xB3\x90\x42"
s = UDPSocket.new
s.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, 1)
s.send("\xff"*6 + mac_addr*16, Socket::SO_BROADCAST, '10.0.0.255', 7)

Blog Bifurcation

May 31st, 2008

One of the reasons I haven’t been blogging much lately is because I’ve decided to bifurcate my blog into a professional/technical blog (which will continue here on lojic.com/blog) and a personal blog, and until I’ve decided on the technology to use for my personal blog I’ve been reluctant to blog much.

The motivation for the split is the feeling that a lot of my non-technical family & friends grow weary of weeding through a lot of techno-geek material to find anything interesting, and folks who read my blog for technical info probably don’t want to weed through the silly videos, etc.

Wordpress has worked fine for my blog thus far, but I want to take the opportunity to develop my personal blog in a new technology more for the learning experience than necessity. I haven’t had time to select the appropriate technology, so I have a bit of analysis paralysis.

The candidates are:

  • Ruby on Rails: I currently develop primarily in Ruby on Rails, so in that respect it would be the logical choice and easiest way to get started; however, it wouldn’t have the benefit of learning a new technology.
  • Arc: I had high hopes for Arc when Paul Graham first released it. I still think it has potential, but that potential is limited by Paul’s interest level and available time. It’s been over 3 months since the last release and that was only a small incremental improvement. The forum seems dead, and the fact that Arc went through a 5 year blackout period makes me wonder whether it will be a dead-end language and a waste of valuable time.
  • Common Lisp: I am leaning toward a Lisp, so if Arc doesn’t pan out, Common Lisp would be a good fallback language. It’s much more mature with robust implementations. It doesn’t provide a nice batteries included experience though, and I’ve been reluctant to collect the necessary libraries from various sources to allow anything remotely similar to Ruby on Rails with respect to ease of development. I think it may have a greater long term potential though, so it may be worth the effort.
  • Scheme: The PLT web server may give me a head start on a Lisp based web site, and Arc is based on MZScheme, so it’s on the short list.
  • Haskell: I know very little Haskell (even less than Lisp which is not much), but I’m intrigued by many aspects of the language. GHC seems to be a great compiler that produces well performing programs. My initial impression is that it will take more effort to learn than a Lisp, but in terms of brain stretching, it has a lot to offer. There is a Haskell based web server available, but like a lot of fringe languages, it appears to be pretty rough around the edges.

I have a vacation coming up, so I think I’ll use some of the down time to do some research and make a decision. Look for the blog bifurcation to happen in the latter half of June. If you have any opinions on the matter, please add a comment :)

Startup School 2008

April 21st, 2008

http://omnisio.com/startupschool08

http://www.justin.tv/hackertv/97554/Startup_School

Peter Norvig, Paul Graham, Marc Andreessen, Mike Arrington, Jeff Bezos, David Heinemeier Hansson, etc.

cmd line history meme

April 19th, 2008

Aaron tagged me

brian@airstream:~$ history 1000 | awk '{a[$2]++}END{for(i in a){print a[i] " " i}}' |
  sort -rn | head

182 cd
141 ls
55 vim
52 ssh
44 timeclock.rb
29 ruby
28 irb
26 fr
26 cat
24 rake
  1. I’ve made a definite switch to emacs, but vim is still handy for the quick view of a file, and I start emacs in the morning via an icon, and it stays up all day - otherwise, it would be way up on the list.
  2. timeclock.rb is a handly little script to parse/format an emacs timelog file - incredibly nice way to track time on various tasks.
  3. fr is an alias for: find . -regextype posix-extended -regex ‘\”.*.r(b|html)’\” | xargs grep

Tag. You’re it :)

Big Dog Robot

March 20th, 2008

Very impressive balance and mobility. A robot from Boston Dynamics.