From: Edwin Fine Date: 2006-11-27T08:23:58+09:00 Subject: Re: Two Advanced Ruby Performance Questions This post may be stating the obvious, but here goes anyway... I hope I am not preaching to the choir. First of all, the most important part of getting high performance is a performance-oriented software and hardware architecture. Second of all, at the code level, the selection of appropriate algorithms is crucial. Finally comes the low-level code tuning. Given an algorithm in Ruby, and the same algorithm in C, the algorithm will perform better in C if the Ruby code consists mostly of primitives (e.g. a += 1, loops with many iterations, conditionals, object creation and destruction, and so on). If the Ruby code is really just calling high-level underlying C library code, then there will not be that much difference. That being said, my experience with getting serious performance out of dynamic languages such as Ruby has been to create extensions in C that do the heavy lifting, and to write code in the dynamic language that consists mainly of calls to the extensions. The wrong thing to do is to write algorithms that make heavy use of fine-grained methods in Ruby. As with any interpreter, the overhead of interpreting the code and calling the method can be a significant proportion of the entire operation. I believe that a very common performance mistake is to design using the wrong level of granularity. This happened a lot with distributed computing (DCOM, CORBA, Web Services) when people would create a fine-grained remote method without considering the overhead of executing it. I formulated a heuristic stating that if the method being called did not take at least 10-100 times longer than the time needed to actually call it (e.g. marshaling, network overhead, etc), it was not coarse-grained enough and should not be a remote method. I think this rule of thumb (with a reasonable choice of constant multiplier, maybe 1000x) could apply to dynamic (or interpreted) languages too. To design a high-performance interpreted application, partition the application appropriately between native code and interpreted code. (The trick is deciding what should be native and what should be Ruby). In doing so, of course, you lose some (maybe a lot) of the portability of the application, and probably maintainability, but that often happens when you are aiming for extreme performance anyway. This point of view may not sit well with Rubyists who want 100% pure Ruby solutions, but as with anything in life, there are always trade-offs. I take a pragmatic point of view, and do what is needed based on priorities. If I can write something in the pure language, I do. If that doesn't make the grade, I either use anther technology or write an extension. -- Posted via http://www.ruby-forum.com/.