4 ms·
Here are some benchmarks on an 8-year-old, 4-core i7 running OSX Sierra. Parsing a 115Mb log file for lines containing a 15-character word (regex: \b\w{15}\b) w
by cutler 8y ago
Here are some benchmarks on an 8-year-old, 4-core i7 running OSX Sierra. Parsing a 115Mb log file for lines containing a 15-character word (regex: \b\w{15}\b) we have:
LANG / TIME* / RAM
JS (Node 11.11) / 8.4s / 100Mb
Ruby 2.6 / 19.1s / 14.8Mb
PHP 7.3 / 4.4s / 5.6Mb
Python 3.7 / 24.7s / 4.2Mb
Perl 5.26 / 14.0s / 1.0Mb
*These figures are for runtime, ie. with startup time deducted. Ruby's startup time (0.55s) is much longer than the other languages (Python:0.06s, Perl:0.02s, PHP:0.14s).
Ruby's memory usage is 3.5 times that of Python for only a 30% speed gain. Perl uses 1/15 of the RAM used by Ruby and is 35% faster but it could be argued that Perl 5's lack of built-in OO accounts for some of this ..... until you look at PHP which has built-in OOP and uses 2/5 of the RAM used by Ruby whilst performing 3.2 times as fast.
I love that Ruby is designed from programmer happiness but the shine starts to wear off when you look at its memory usage. Slow is bearable as it's only marginal but Ruby's memory usage is orders of magnitude higher it seems. Matz's goal of making Ruby 3 times faster is only half the battle, maybe even only a third. If an increase in speed comes at the expense of even greater memory use then Ruby will not survive.
- faebi 8y agoWhich method did you use to match the line in Ruby? I noticed String[/\b\w{15}\b/] performs way better than String.match(/\b\w{15}\b/).
- cutler 8y agoThe Ruby code is: IO.foreach('logs1.txt') {|x| puts x if /\b\w{15}\b/.match? x }
- yxhuvud 8y agoWhat happens if you lift the regexp out of the block and reuse the same regexp instance?
- cutler 8y agoTried: regex = Regexp.new '\b\w{15}\b' IO.foreach('logs1.txt') {|x| puts x if regex.match? x } ... but performance and RAM usage were identical.
- JohnBooty 8y agoRuby's smart enough to freeze regexen by default. I think that landed around 2.0/2.1/2.2 pry(main)> 3.times { puts /i_am_a_reg_ex/.object_id } 70131978677720 70131978677720 70131978677720
- cutler 8y agoIt could be argued anyway that String[/\b\w{15}\b/] is not idiomatic.
- tinco 8y agoIf Ruby was performant enough to disrupt the web app industry ten years ago, it is performant enough today. Ruby's survival is not dependent on trivial fluctuations in benchmark numbers. Ruby is just as shiny as it was in 2006, if not more so. If you feel happy writing log parsers in JavaScript or PHP well then all power to you, but I'd rather chew on a shoe. I do my data processing in Ruby, if there's a performance issue I'll fork out to a little Go widget. But that's when I need a factor ten improvement or more.
- pjmlp 8y agoRuby disrupt those that were never exposed to AOLServer or Zope, we just had a sense of deja-vu.
- tinco 8y agoCould very well be, I was a young developer when the Rails hype happened, to me it was disrupting clumsy Java and .Net web architectures, and the ugly ad hoc PHP methodology. I have never heard of AOLServer or Zope, no one ever told me about them.
- hangonhn 8y agoThe problem for Ruby on Rails is that a lot of its good idea were eventually borrowed while it was encumbered by Ruby's performance. No one develop web apps like they did on Java when Rails came out. A lot of good ideas from Ruby and RoR became mainstream and popular but done on faster platforms.
- andyfleming 8y agoWhy was the memory usage so high for the node/js version? Was the whole file being loaded into memory? Care to share the code?
- cutler 8y agovar fs = require('fs'), byline = require('byline'); var stream = byline(fs.createReadStream('logs1.txt', {encoding: 'utf8'})); stream.on('data', function(line) { if (line.match(/\b\w{15}\b/)) console.log(line); });
- Can_Not 8y agoThat regex should have been declared a variable on its own line.
- tyingq 8y ago"it could be argued that Perl 5's lack of built-in OO" That's interesting to me. I consider bless() and package namespaces to be "built in OO." Is there some OO concept that combo doesn't provide? Also, for "Parsing a 115Mb log file for lines containing a 15-character word" ? Wouldn't that just be: perl -ne 'print if /\b\w{15}\b/' I'm surprised that's not faster.
- cutler 8y agoI was trying to create a level playing field as PHP and Python don't lend themselves to one-liners as well as Ruby and Perl. If blessing a hashref is real OO why has so much energy been expended on Moose and its offspring? Before I left, back in 2013, there was also much gnashing of teeth over whether Perl needed a MOP so I don't think everyone agreed that bless() is enough.
- tyingq 8y ago"If blessing a hashref is real OO why has so much energy been expended on Moose and its offspring?" That's a good question. It's always mystified me. A little boilerplate doesn't bother me. As far as I can tell, it's because people didn't like writing the constructor boilerplate and getters/setters. Maybe for the "isa" pretend types?
- joevandyk 8y agoNot sure that comparing base memory usage on tiny programs that aren’t including any commonly used libraries is that useful.
- cutler 8y agoI'd argue that excluding libraries gives a clearer impression of the relative performance of the languages themselves.
- bluedino 8y agoIf memory mattered that much we’d all still be using Perl.
- michaelmrose 8y agoAre you interested in sharing the log file if it doesn't contain anything sensitive or a reasonable facsimile with scripts?