Andrew Rollins Technology, entrepreneurship, the Internet, and video games

17Nov/090

Ruby MD5 and SHA1 Digest Benchmark

I did a benchmark of MD5 and SHA1 digests in Ruby. The benchmark was done in Ruby 1.8.6 on Windows.

The code used to benchmark:

require 'benchmark'
require 'digest/sha1'
require 'digest/md5'
require 'base64'

# Demonstration of digests

puts "SHA1.hexdigest     #{Digest::SHA1.hexdigest('test')}"
puts "MD5.hexdigest      #{Digest::MD5.hexdigest('test')}"
puts "SHA1.digest        #{Base64.encode64(Digest::SHA1.digest('test'))}"
puts "MD5.digest         #{Base64.encode64(Digest::MD5.digest('test'))}"
puts "MD5.digest.inspect #{Digest::MD5.digest('test').inspect}"

print "\nSHA1.digest bytes "
Digest::SHA1.digest('test').each_byte {|c| printf("%4d", c) }
print "\nMD5.digest bytes  "
Digest::MD5.digest( 'test').each_byte {|c| printf("%4d", c) }
puts "\n\n"

# Benchmark

TIMES = 50_000

Benchmark.bmbm do |b|
b.report("sha1 hexdig") { TIMES.times do |x|; Digest::SHA1.hexdigest(x.to_s); end }
b.report("md5  hexdig") { TIMES.times do |x|; Digest::MD5.hexdigest(x.to_s); end }

b.report("sha1 digest") { TIMES.times do |x|; Digest::SHA1.digest(x.to_s); end }
b.report("md5  digest") { TIMES.times do |x|; Digest::MD5.digest(x.to_s); end }
end

The output:

SHA1.hexdigest     a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
MD5.hexdigest      098f6bcd4621d373cade4e832627b4f6
SHA1.digest        qUqP5cyxm6YcTAhz05Hph5gvu9M=
MD5.digest         CY9rzUYh03PK3k6DJie09g==
MD5.digest.inspect "\t\217k\315F!\323s\312\336N\203&'\264\366"

SHA1.digest bytes  169  74 143 229 204 177 155 166  28  76   8 115 211 145 233 135 152  47 187 211
MD5.digest bytes     9 143 107 205  70  33 211 115 202 222  78 131  38  39 180 246

Rehearsal -----------------------------------------------
sha1 hexdig   0.797000   0.000000   0.797000 (  0.796000)
md5  hexdig   0.641000   0.000000   0.641000 (  0.641000)
sha1 digest   0.625000   0.000000   0.625000 (  0.625000)
md5  digest   0.500000   0.000000   0.500000 (  0.500000)
-------------------------------------- total: 2.563000sec

user     system      total        real
sha1 hexdig   0.750000   0.032000   0.782000 (  0.781000)
md5  hexdig   0.593000   0.000000   0.593000 (  0.594000)
sha1 digest   0.594000   0.031000   0.625000 (  0.625000)
md5  digest   0.469000   0.000000   0.469000 (  0.468000)

As expected, digest methods are faster than hexdigest and MD5 is faster than SHA1.

Filed under: Ruby No Comments
6Jun/080

More on Maglev

After a little more searching around, I found some good pieces which bring back to reality the performance claims of Maglev and potential problems with object oriented databases. Let's not forget that Maglev isn't even out yet, and we have no idea if it'll be what it claims to be. In the mean time, there are other well known Ruby intrepreters and VMs, such as Ruby MRI, JRuby and YARV.

Check out these in depth looks at Maglev:

This is by Charles Nutter, contributor to a popular Ruby intrepreter written in Java called JRuby. In it, he calls Maglev vaporware, thus Gemstone's Maglev performance claims don't mean much at this point. The key to his point is that we have no idea if Maglev is fully Ruby compliant, and to prove his point, he shows us actual numbers for performance gains that can be achieved in JRuby by removing some compliance features.

Sho Fukamachi questions the Maglev performance claims and the usefulness of OODBs.

My Thoughts

My point in the last post was that mapping from OO languages to relational DBs can get ugly. Naturally then, I'm curious about other ways of looking at the problem, but other solutions could have problems, too.

Design patterns such as Ruby's ActiveRecord have popped up to abstract relational systems to an OO style. However, abstracting relational DBs to an OO model can often result in more DB queries, and it's easy for inexperienced programmers to write bad, query heavy code. They just see everything as objects, and they don't understand the consequences of their manipulations.

For this reason, it's no mystery to me why people often complain about Ruby's scalability. It isn't necessarily Ruby that's the problem. It might be the programmers. Perhaps an OODB is the solution since it would remove the need to map and reduce the aforementioned consequences, but I really don't know.

31May/083

On Database Abstraction, PHP, and Ruby

It took me a couple days on my current PHP/MySQL project to get the DB abstraction with proper error handling, input validation, and relational support coded to the point where I'm happy with the model. This was after trying Zend_Db, Doctrine, and Propel, which are all good libraries, but I hit points where the work of getting it to do what I wanted efficiently just wasn't worth it. I decided it would be faster to just roll my own slim library.

I'm always mystified at why DB models are such a hassle to code, so I spent a little time reading. I think I get it now. It has to do with the mapping problem between relational systems and object oriented systems.

Ted Neward, writer of several books on C# and Java, calls this "The Vietnam of Computer Science". What he's saying is that object-relational mapping (ORM) quickly reaches a point of diminishing returns. The problem stems from the conceptual disconnect between the language and the data store.

Hoping to shed additional light on the subject, I went looking for alternative perspectives to my PHP/MySQL solution. Since it's all the rage for ease of use, I was mostly curious about Ruby, the Rails framework, and object oriented databases.

Ruby is certainly different, but after some reading, I'm starting to understand why the language lends itself better to the OO style of DB abstraction. On top of that, Rails has powerful scaffolding that lets you flesh out pieces very fast without the code getting ugly. With ActiveRecord in mind from the ground up, things can be pretty elegant some times.

I also found some really cool systems for bridging the gap between languages and data stores. For instance, check out MagLev for Smalltalk/Ruby. Imagine using an OO DB so you don't have to do the relational mapping, doing it in a distributed fashion, and using things like shared memory more efficiently as an object staging area between your running site scripts and the DB. That's kind of MagLev.

All of this is interesting, but for the current project I'm sticking with PHP. However, on the next project I might try Ruby on Rails. I want to see first hand if and how it overcomes some of the challenges.

On a slightly tangential subject, a part of me really dislikes the weak typing of both Ruby and PHP. The net effect in PHP is that you pretty much end up using arrays for everything, making it hard to keep track of structure. Ruby on Rails does get around some of the weak typing issues with some better built-in validation, scaffolding, and member attributes (I'm not sure if that's what they call them). Sometimes I'd rather be doing C#.

   
Close
E-mail It