From: Ben Giddings Date: 2003-09-16T07:40:34+09:00 Subject: Re: performance and style advice requested Alex Martelli wrote: > Heh -- matter of taste, I guess; what _I_ personally find ugly is > that leading $, and I left the underscores in to try to ameliorate > that. Of course, nothing stops you from moving to a camelCaseish > $factMemo -- however, not only do I personally find that less > readable, but I'd also like to leave a hint that the memo is an > internal implementation detail, not a feature meant for external > consumption, and I like the convention of a leading _ for that. > (Of course, I _could_ wrap up the fact function and its memo in > a single package in any of various ways, I'm sure, so the "hint" > aspect is quite secondary). Sorry, I wasn't completely clear. It's the leading underscores that I object to. I don't mind underscores_in_names at all. The reason I dislike leading underscores is that they tend to be holdovers to languages that don't have proper access control. (C mostly) In any situation where someone is tempted to use them, I find that they normally should be using something else (like using instance variables which are by their nature private). As for the ugliness of '$', it has been said that it is supposed to be ugly. Global variables in general are ugly code, and so people tend to avoid using '$', making their programs better. > However, it will be very rare for any given x to NOT be already > memoized (i.e., fact is called with a very modest variety of > arguments, compared to the number of calls to it, in any typical > combinatorial-arithmetic application); while calls with x<0 are > going to be exceedingly rare. So, the relative costs of array > indexing vs (operator< + conditional) shouldn't matter -- trying > to get the result off the array first _should_ be a win anyway > (or at least, that's what my optimization experience as built on > a wide variety of languages tells me -- admittedly I have no such > experience in Ruby, but I fail to see how it would differ on this > specific point). Ah, I see what you mean. I'm sure you're right that it's faster the way you now have it. I didn't think things through fully and realize that 95% of the time the number will be positive and so it will have to evaluate the conditional then do the array lookup. It is also going to be *much* faster to do the array lookup rather than the triple conditional for the "comb" case. > Actually, I find the oneliner body > > $_fact_memo[x] ||= if x<0 then 0 else x * fact(x-1) end > > quite clear and readable, given that one must grok the semantics > of ||= anyway. Yeah. That "||=" is a little hard the first time you notice it, but once you realize how useful it is, you'll use it so often it becomes second nature. You could also use the other form, which as a C++ coder I'm sure you'd recognize: $_fact_memo[x] ||= (x<0) ? 0 : fact(x-1) Which also works in Ruby. I don't like it as much, but it's a preference I guess. > Very good point, and an excellent suggestion at least for concision & > readability purposes -- I'll definitely keep the idiom > [] ||= > in mind for the future -- thanks! Note it also works for non container objects: var ||= "new val"; and in other types of expression: var = other_var || "default val" > Performance-wise, there ain't all that much in it for this app. > > I've managed to scrounge some diskspace on Linux and compile both > Python and Ruby (1.6.8 only, unfortunately -- the link I downloaded > from mentioned 1.8, but I found out only when everything was built > that I had 1.6.8 instead [how I found out: I had thoughtlessly left > a trailing colon on an "if" statement -- 1.8 was quite cool about > it, while 1.6.8 gave me three weird errors for that one mistake;-)]. If you have the chance to try it on Ruby 1.8 I (and others I'm sure) would be interested in hearing how it stacks up both to Python and to Ruby 1.6. (In another post) Alex Martelli wrote: >> While I doubt you should compare these languages on performance merits > *blink* why not, pray? While clarity, productivity, simplicity, and so on, > are surely all crucial attributes in a language, what's wrong with wanting > to ascertain how it performs (when used in the best/fastest way, at least) > in typical problems in one's domains of interest...? I don't think that it's wrong to compare the speed of the languages. I just wouldn't be surprised if Python is faster by a healthy margin, especially for a very simple numerical program like this. In Ruby, *everything* is an object, including numbers. This has certain advantages, but definitely carries some speed penalties. By using a scripting language rather than assembly or C, you've already decided you're willing to sacrifice some performance for ease of use. I expect that both Perl and Python would beat Ruby in nearly any benchmark, but I find Ruby much easier to use than both. For tasks where a scripting language is appropriate, I choose Ruby.