Hacker News new | ask | show | jobs
by ajamesm 3379 days ago
70x faster? If Crystal gets its own port of Ruby on Rails, oh boy.
3 comments

70x faster, with the caveat that the way that Ruby code is written really does not lend itself to speed.

E.g. using method calls inside the class instead of accessing instance variables instantly springs to mind, as does the "unsorted priority queue" which is basically a horrible abuse of Array but wrapped in a class that makes it even slower by adding additional method calls for every operation.

That's not to diminish the speedup Crystal gets, because it does illustrate how slow MRI's method calls are, but it'd be interesting in seeing a comparison with an astar implementation that was actually written to be fast in Ruby.

Also would be very interesting to see a comparison with jRuby+Truffle, of course.

Author of the article here. This implementation of A* was me playing around. It is definitely not optimized for either Ruby or Crystal It was merely a chunk of Ruby code that I had lying around. You are right about the unsorted queue being a hack around Array, but it was part of another experiment of using a "Fast Stack"[1] for the A* algorithm. It allowed me to swap in other Queue implementations easily.

The point of the article was merely "How much work does it take to port Ruby to Crystal" The performance differences were just fun to see, not the intent.

If I get time, maybe I'll run this through jRuby+Truffle as a comparison, that would be interesting to see.

[1] https://github.com/SteveRabin/JPSPlusWithGoalBounding

That would definitely be interesting if you run it on the same hardware.
Crystal does the same as ruby for instance variable access, it's just that such methods are such an easy target for inlining by LLVM there's practically no performance penalty. The flexibility of gets and sets simply being method calls is very awesome and very worth it.
It sounds like more substantial semantic differences then, as in the Ruby case the challenge with making it fast is that you can't take shortcuts like that without first verifying that there are no possible calls to any code that can have side effects like making changes to the receiver - you need to be prepared to "deoptimize" the code back to doing full method calls at any point, as in the general case you have no guarantee that the code will remain a simple getter/setter.
There are quite a few web frameworks headed in that direction: https://github.com/veelenga/awesome-crystal#web-frameworks
Web server output is roughly 2x as per its home page: https://crystal-lang.org/?utm=source-temp

This A* example is contrived.