Performance and style advice requested

Why not use a constant?
why use a constant?
nikolai

···


::: name: Nikolai Weibull :: aliases: pcp / lone-star / aka :::
::: born: Chicago, IL USA :: loc atm: Gothenburg, Sweden :::
::: page: www.pcppopper.org :: fun atm: gf,lps,ruby,php,war3 :::
main(){printf(&linux[“\021%six\012\0”],(linux)[“have”]+“fun”-97);}

It just makes it worse. The $ is ugly for a reason–the use of
global variables is discouraged. The Ruby Way to do it would be

Ironically, I find @var far uglier than $var - the @ is denser and
blockier, so it takes up a disproportionate amount of visual attention.
you realize that you two are discussing which of Ruby’s scoping
specifiers are prettier than the other, or? this does not seem to me to
have very much to do with the original problem? can’t we please keep
stuff like this out of the threads? it gets really boring following a
thread when it spans a myriad of subtrees of mildly related topics. and
in any case, using a global variable seems to be fine in such a short
script, but should of course be an instance variable in any well-formed
code. and, if you find the ‘at’ sign (@) to be too dense, using another
font, or creating your own would perhaps fix this?
nikolai

···


::: name: Nikolai Weibull :: aliases: pcp / lone-star / aka :::
::: born: Chicago, IL USA :: loc atm: Gothenburg, Sweden :::
::: page: www.pcppopper.org :: fun atm: gf,lps,ruby,php,war3 :::
main(){printf(&linux[“\021%six\012\0”],(linux)[“have”]+“fun”-97);}

Martin DeMello wrote:

···

Dave Brown dagbrown@lart.ca wrote:

It just makes it worse. The $ is ugly for a reason–the use of
global variables is discouraged. The Ruby Way to do it would be

Ironically, I find @var far uglier than $var - the @ is denser and
blockier, so it takes up a disproportionate amount of visual attention.

Its ugliness is good too – it is good practice to avoid accessing your
own instance variables directly by using an accessor methods instead.
If you do this, you get better code and fewer "@"s. Sure, you’ll still
have more "@"s than "$"s, but dont think that “@” is good and “$” is bad.

Ben

Ben Giddings wrote:

Alex Martelli wrote:

Heh – matter of taste, I guess; what I personally find ugly is

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)

Or Python – no “access control” whatsoever, just advisory indications
of what’s meant to be “published” and what’s meant to be for internal use
only. Just the time saved not having to decide what’s private, public,
or protected (Stroustrup regrets having introduced the complication of
that third intermediate classifier – see his book “Design and Evolution
of the C++ programming language”) is by itself a huge performance boost.

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).

Given that in Ruby one can always, anywhere, reopen a class and add
getters and setters for all attributes of interest in a few keystrokes,
I guess the “by their nature private” issue doesn’t cost you much (except
some wasted performance, perhaps?) but doesn’t buy you much either (no
more than in C++ with its typical “#define private public” trick, say).

Java, at least in theory, does enforce privacy strictly (but I’ve
seen too many security issues with JVM’s to trust it, personally;-),
so there are “real” costs and benefits involved; the same might be said
of a very few implementations of C++ (I’m thinking of SOM, but it’s SO
many years since I used it that I may have the details wrong – clearly
the strict enforcement didn’t do much for the market success of those
implementations of C++ – against MS, Borland, and gcc, say;-). But as
long as the “protection” is fundamentally just advisory, I don’t think
there’s much in it, either as a cost or as a benefit. I’d rather have
a simpler language relying on a simple naming convention than a more
complicated language with elaborate advisory mechanisms, personally.

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.

I have nothing against this line of reasoning. I’m still allowed to
make the code a BIT less ugly (in my eyes) by using $_foo instead of
base $foo, though. By the same token, literals in your code are ugly
(they should all be constants, right?) – so do you object to Ruby
letting me write a prettier (and more readable, IMHO) 1_000_000
rather than an uglier (harder to read, must count 0’s) 1000000 …?-)

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.

Ayup. I did try both ways, btw – hard to measure the difference
in my current benchmark (it just doesn’t exercise fact enough, and
comb barely enough), but fwiw it does seem to be faster with the
“if” inside. (Anybody who’s done enough optimization will tell you
that rationalizing why A is faster than B is all nice and good, but
until and unless you’ve MEASURED them, you don’t really KNOW…!-).

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

Yeah, it was a little hard, about 15 years ago I think, when I
first met it – in Griswold’s “Icon” programming language;-).

once you realize how useful it is, you’ll use it so often it becomes
second nature.

No doubt. The Python equivalent (for a dict only, not a list, but
Python dicts are so fast that they’re preferable to lists in all of
these cases – yep I did measure both ways;-) would be:

return fact_memo.setdefault(x, ...whatever...)

BUT the applicative-order (vs normal-order – aka eager vs lazy)
semantics of function calls means that “whatever” would have to be
computed in all cases (even when x IS already a key in fact_memo),
making this construct useful in substantially fewer cases.

You could also use the other form, which as a C++ coder I’m sure you’d
recognize:

$_fact_memo ||= (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.

A dream I’ll surely never be able to afford would be to have the same
projects tackled by pair of otherwise equivalent teams, but with two
languages that differ in just ONE characteristic – surely, in theory,
that would be a wonderful way to measure the worth of that one
feature. Out of all the possible "ONE characteristic"s to be so
tested, the single one I’d be most interested in studying that way
(if I had a few megabucks to spare in order to pay the temas;-) might
be the enthusiastic “more than one way to do it” philosophy of Perl
and Ruby, vs the principle which the C Standard phrases as “provide
only one way to do an operation”, and the Python Zen phrases as
“There should be one-- and preferably only one --obvious way to do it.”.

My guess is that, while there might be tradeoffs depending on the
quality, personality, etc, of the programmers, for small teams,
as teams grow larger, uniformity (with its attendant help in
moving towards the “collective code ownership” ideal of XP) would
no doubt become preferable. Of course, one could try to enforce
uniformity by other means (static code checkers, regular code
inspections, etc, etc), but they’re all costlier than not having
the variability in the language in the first place (and not having
the variability also makes the language smaller and thus faster to
learn, to master, to implement – again, a “spirit of C” principle,
“Keep the language small and simple”, which I revere).

Oh well, it will no doubt remain an (educated) guess – and the
uniformity, even in C or Python, is only an ideal, anyway.

But for the life of me I just can’t see why, when one has
“if a then b else c end” working perfectly as both an expression
and a control statement, one would WANT to weigh down the language
with an alternative but equivalent syntax “a?b:c”. I guess a
definitely-NOT-postmodern aesthetics which appreciates simplicity,
uniformity, etc, makes me characterially unsuited to appreciate
this “enthusiastic redundance” idea of Perl and Ruby!-)

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”;

Noted, thanks (I also notice the redundant trailing “;”“”…?-) – I
guess this means that keeping variables initially undefined may be
a sensible strategy in Ruby where it wouldn’t be in C or Python.

and in other types of expression:

var = other_var || “default val”

Sure (but that’s quite OK in Python too, since you can more legibly
spell “||” as “or” in this case, and then it does short-circuit –
the Python issue is that there’s no shortcircuiting “or=”, as well
as the fact that undefined variables raise exceptions rather than
quiety returning nil [or None, in Python]).

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.

No doubt I will once I’m back home – I find that I can’t work on
this as much as I had hoped while on this business trip.

(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.

I fail to see where the speed penalties are inherent, given that the
semantics of integer numbers in Python and Ruby are so similar now
(e.g., fixnums, aka “int”, now transparently give bignum, aka “long”,
results in Python, too). Indeed, in Python, there isn’t that deep
a distinction between int and anything else as there seems to be in
Ruby between Fixnum (and true and false and nil - that’s all I think?)
and everything else – surely by singling out fixnums that way Ruby
IS gaining some speed advantage, at least for those computations (a
fair chunk) that stay within the roughly-one-billion limit in this
benchmark. Besides, it appears to me (from that one attempt to run
the profiler) that the bottleneck isn’t in the arithmetic, anyway,
but rather in the generation of the subsets with that recursive
iterator in each language (so perhaps my next step should be some
attempt at recursion-elimination, muses he consequently). In other
words, I’m not really sure this IS “a very simple numerical program”;
where I come from (Fortran, my first language, back then…) by “a
very simple numerical program” we mean something for which enumerating
subset by recursion would never qualify (let alone iterators).

Anyway, I’ll grow this to definitely-NOT-simple eventually. Will
the extra complication of the problem being solved favour Ruby’s
performance? Stay tuned…;-).

I’ll accept your evaluation that you’re not surprised if Python is
faster by a healthy margin, but I’d rather a different explanation
than the one you give. WHAT do you think is NOT “an object” in
the Python program, giving Python an intrinsic speed advantage…?

I can’t see anything, myself. Indeed, I’d look at the reverse issue:
in Python “a tuple of numbers” is an object and thus can index right
into a dictionary – in Ruby, I was informed, when it LOOKS like I’m
using a tuple to index into a Hash, in fact the interpreter is working
hard under the covers at forming a string out of that tuple – so, it
seems to me, the performance handicap is that “tuple” is NOT an
object which can (directly) index a Ruby Hash (here I’ve fixed it, as
suggested, by using x<<16+y, rather than [x,y], as the key into the
Hash, but I wonder about what happens when I have several numbers
instead of just a pair of them – as will soon be the case as my
example script grows more ambitious… but the numbers will be small,
so perhaps enough << and + will work well anyway – we’ll see!).

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

You might be surprised. Try coding in standard C or assembly a program
that must work with integers as large as 52!, without using some finely
tuned external library for the pupose, and we’ll see what performance
you do get…;-). [In practice, multiple-precision arithmetic is NOT
trivial to code with decent performance]. Sure, I could use GMP, say –
but then I could use it for Ruby or C just as well, and the variability
becomes unbounded. I am interested in comparing standard languages
as opposed to languages coupled with any one of a zillion potential
add-on libraries, after all.

And I’m not interested in blowing up my program by an order of magnitude
so I can include in it complete sources for multi-precision arithmetic
and hash tables. I want to compare programs of comparable complexity,
thus, languages of comparable semantic level – as indeed Python and
Ruby easily prove to be on this problem, with the code in the two
languages in such an obvious, nearly 1:1 correspondence. Given that the
semantic level is just about the same, performance discrepancies as
high as 2 or 3 times are STILL pretty mysterious to me.

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.

I know of no tasks where “a scripting language” is NOT appropriate,
except operating systems (kernels and drivers), and accelerators for
“scripting languages” (and, in the pypy project, we’re trying to drop
the second proviso, and prove that higher level languages CAN in
fact be made intrinsically faster than lower level ones – but that’s
a longer-term goal, of course;-). So, anyway, I’m trying to see the
“easier to use” part – which includes, IMHO, performance issues where
appropriate. I can easily see it wrt Perl – the OO, the fact that
the language is smaller and more elegant. But where does it come wrt
Python, given that Python is the smaller language (no deliberate
redundance) and the “elegance” pro’s and con’s clearly go both ways
(Ruby has some very elegant parts, those designed from scratch, but
e.g. all of those $_ $` $’ $! etc etc that it borrowed from Perl
surely can’t be considered elegant…???)…? That’s what I’m trying
to find out. Perhaps it’s domain dependent and just doesn’t show up
at all in combinatorial-arithmetic? OK, then once I’ve exhausted that
I’ll move on to something else – after all Python and Ruby are clearly
both perfectly general-purpose languages, so it’s not as if I’ll soon
run out of application domains to explore, hm?-)

Alex

(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.

Err…isn’t everything an object in Python as well?

~$ python
Python 2.3 (#1, Aug 4 2003, 08:45:40)
[GCC 3.2.2 (CRUX)] on linux2
Type “help”, “copyright”, “credits” or “license” for more information.

n = 5.5
dir(n)
[‘abs’, ‘add’, ‘class’, ‘cmp’, ‘coerce’,
delattr’, ‘div’, ‘divmod’, ‘doc’, ‘float’,
floordiv’, ‘getattribute’, ‘getnewargs’, ‘hash’,
init’, ‘int’, ‘long’, ‘mod’, ‘mul’, ‘neg’,
new’, ‘nonzero’, ‘pos’, ‘pow’, ‘radd’, ‘rdiv’,
rdivmod’, ‘reduce’, ‘reduce_ex’, ‘repr’,
rfloordiv’, ‘rmod’, ‘rmul’, ‘rpow’, ‘rsub’,
rtruediv’, ‘setattr’, ‘str’, ‘sub’, ‘truediv’]
n.add(4)
9.5
n.int()
5

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.

Yes, I have found that both Perl and Python seem to be faster than Ruby
for running the code, but Ruby is faster for writing it. :slight_smile:

Jason Creighton

···

On Tue, 16 Sep 2003 07:40:34 +0900 Ben Giddings bg-rubytalk@infofiend.com wrote:

Alex Martelli aleaxit@yahoo.com skrev den Tue, 16 Sep 2003 02:48:00 +0900:

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…? A 10% or 20% difference is hardly ever going to matter, but factors of 2 or 3 might
well make the difference, in practice, between two languages of otherwise
comparable merits – and that’s what I am observing here, so far (at least
in the toy/starting problem which I’m using as a warm-up exercise – we’ll
see what happens when I move to bigger and more interesting problems, e.g.
I cannot exclude that Ruby’s performance might “scale up” better, or whatever).

Nothing wrong with the comparison but:

1, If performance is REALLY important to you, you wouldn’t use Python or Ruby anyway, IMHO, so their relative performance
is less important than any of them compared to C.

2, Performance is hard to compare since algorithmic differences is often
so much more important than the gains you get with “tweak-like”
performance tuning (for example the 16-time speedup of your problem I presented earlier)

3, There has been a couple of troll-like “Ruby has nothing to offer
compared to Python” threads in the last couple of weeks

so please understand my response in that context.

Regards,

Robert

I would change this to:

def fact(n)
@facts ||= [1]
@facts[n] ||= (@facts.length…n).inject(@facts.last) { |f, i|
@facts[i] = i * f
}
end

-austin

···

On Tue, 16 Sep 2003 03:22:32 +0900, Robert Feldt wrote:

austin ziegler * austin@halostatue.ca * Toronto, ON, Canada
software designer * pragmatic programmer * 2003.09.15
* 15.43.57

“Robert Feldt” feldt@ce.chalmers.se schrieb im Newsbeitrag
news:oprvjzzqcmoglyup@mail1.telia.com

Robert Feldt feldt@ce.chalmers.se skrev den Tue, 16 Sep 2003 03:14:05
+0900:

@facts = [1]
def fact(n)
@facts[n] ||= (@facts.last…n).inject(1) {|f, i| @facts[i] = i * f}
end

Oops, it should be

@facts = [1]

IMHO rather:
@facts = [0,1]

def fact(n)
@facts[n] ||= (@facts.length…n).inject(@facts.last) {|f, i| @facts[i] =
i * f}
end

And, I think there’s a subtle bug with the inject parameter. Another
version:

def fact(n)
@facts ||= [0,1]
@facts[n] ||= (@facts.length…n).inject(@facts[-1]) {|f, i| @facts[i] = i

  • f}
    end

And: Dave, thanks for this inspiring reduction! I haven’t grown familiar to
inject() yet…

Kind regards

robert

Because it looks better than a global, and exhibits what I consider to be
better behaviour overall.

-austin

···

On Tue, 16 Sep 2003 04:47:27 +0900, Nikolai Weibull wrote:

Why not use a constant?
why use a constant?


austin ziegler * austin@halostatue.ca * Toronto, ON, Canada
software designer * pragmatic programmer * 2003.09.15
* 16.55.48

lol. Aesthetically, I prefer @ to $. One is circular, the other is
serpentine. One represents the spiritual, the other lucre.
Aesthetically, I like a little humor in the threads.

Regards,

Mark

···

On Monday, September 15, 2003, at 05:15 PM, Nikolai Weibull wrote:

It just makes it worse. The $ is ugly for a reason–the use of
global variables is discouraged. The Ruby Way to do it would be

Ironically, I find @var far uglier than $var - the @ is denser and
blockier, so it takes up a disproportionate amount of visual
attention.
you realize that you two are discussing which of Ruby’s scoping
specifiers are prettier than the other, or? this does not seem to me
to
have very much to do with the original problem? can’t we please keep
stuff like this out of the threads? it gets really boring following a
thread when it spans a myriad of subtrees of mildly related topics.
and
in any case, using a global variable seems to be fine in such a short
script, but should of course be an instance variable in any well-formed
code. and, if you find the ‘at’ sign (@) to be too dense, using
another
font, or creating your own would perhaps fix this?
[snip]

“Ben Giddings” bg-rubytalk@infofiend.com schrieb im Newsbeitrag
news:3F66416C.5000800@infofiend.com

Martin DeMello wrote:

It just makes it worse. The $ is ugly for a reason–the use of
global variables is discouraged. The Ruby Way to do it would be

Ironically, I find @var far uglier than $var - the @ is denser and
blockier, so it takes up a disproportionate amount of visual
attention.

Its ugliness is good too – it is good practice to avoid accessing your
own instance variables directly by using an accessor methods instead.
If you do this, you get better code and fewer "@"s. Sure, you’ll still
have more "@"s than "$"s, but dont think that “@” is good and “$” is
bad.

I didn’t measure this but I’d guess that a direct access is indeed faster
(mind the subject). :slight_smile:

robert
···

Dave Brown dagbrown@lart.ca wrote:

Alex Martelli wrote:

Or Python – no “access control” whatsoever, just advisory indications
of what’s meant to be “published” and what’s meant to be for internal use
only.

Well, that’s technically true of Ruby as well. You can get access to
a private variable at any time, if you try hard enough (using
instance_eval for example). It’s just that you’re encouraged to use
getter/setter methods, and to provide them for only the attributes you
want exposed.

I think the only thing it buys you is that it forces you to consider
“which of these attributes is internal state, and which do I want others
to have access to?” whenever you’re writing something. My guess would
be that that lends itself to a cleaner design. It seems to me that the
way Python works lends you to “I’ll make Foo with attributes bar and
bat, now which ones of these are really actually private?” then adding
an underscore to their names vs. “I’ll make Foo with attributes bar and
bat, now which ones of these are actually public?” then adding an
accessor for that variable.

Afterall, there’s nothing stopping you from using structs instead of
classes in C++. My understanding is that the only difference is that a
struct is by default all public, and a class is by default all private.
But people always use classes. Why? Probably that’s just the way
they learned, but maybe it’s because it’s more natural to start with
everything private, then expose only what you think is necessary.

I have nothing against this line of reasoning. I’m still allowed to
make the code a BIT less ugly (in my eyes) by using $_foo instead of
base $foo, though. By the same token, literals in your code are ugly
(they should all be constants, right?) – so do you object to Ruby
letting me write a prettier (and more readable, IMHO) 1_000_000
rather than an uglier (harder to read, must count 0’s) 1000000 …?-)

Yes, I think most literals are bad, and using constants is good, within
reason. I’d certainly cringe at “if x < THE_NUMBER_ZERO” though. Do
whatcha want when it comes to $_var, I just think it’s ugly, but I think
a lot of people’s code is ugly, so don’t mind me. :slight_smile:

be the enthusiastic “more than one way to do it” philosophy of Perl
and Ruby, vs the principle which the C Standard phrases as “provide
only one way to do an operation”, and the Python Zen phrases as
“There should be one-- and preferably only one --obvious way to do it.”.

Actually, my understanding of matz’ design philosophy is that it’s more
like Python’s than Perl’s. My understanding was that Python’s was more
like “There should be one – and preferably only one – way to do it.”,
(i.e. the obviousness didn’t come into it) where Ruby’s was “There
should be one obvious way to do it (but other ways are ok too)” So in
Python there should never be two ways of doing something, unless
absolutely necessary, but in Ruby there can easily be multiple ways of
doing something, but one should be the obvious choice. You know Python
far better than I do though, so maybe my understanding is wrong, but I
can say with confidence that Ruby has many more obvious solutions than
does Perl.

Note it also works for non container objects:

var ||= “new val”;

Noted, thanks (I also notice the redundant trailing “;”“”…?-) – I
guess this means that keeping variables initially undefined may be
a sensible strategy in Ruby where it wouldn’t be in C or Python.

Oops! An artifact of coding all day in C, I’m afraid. And a nitpick,
in Ruby variables aren’t quite initially undefined, they’re set to
“nil”, the instance of the Nil class. At least, that’s my
understanding. I don’t think you can have a truly undefined variable in
Ruby.

I fail to see where the speed penalties are inherent, given that the
semantics of integer numbers in Python and Ruby are so similar now
(e.g., fixnums, aka “int”, now transparently give bignum, aka “long”,
results in Python, too).

Sorry, most of my python knowledge is way out of date. I used it for a
while seriously in '97, but not too much since then. If I recall
correctly, at that point there was a clear distinction between built-in
types and classes, and there were also certain classes which couldn’t be
subclassed. But I have heard that changed.

Anyway, I’ll grow this to definitely-NOT-simple eventually. Will
the extra complication of the problem being solved favour Ruby’s
performance? Stay tuned…;-).

I’d also be curious to have your impressions on things other than speed,
like how long it took to write the programs, how maintainable they seem
to be, how easy they are to modify, that sort of thing. It’s a bit of
an unfair comparison since you know Python well, but this is the sort of
area that I think Ruby tends to win out in.

I’ll accept your evaluation that you’re not surprised if Python is
faster by a healthy margin, but I’d rather a different explanation
than the one you give. WHAT do you think is NOT “an object” in
the Python program, giving Python an intrinsic speed advantage…?

I haven’t used Python 2.3 yet, and haven’t used much Python at all in a
while, but I was under the impression that integers and other basic
types weren’t quite full-fledged objects. I seem to remember that they
could act as objects, but there was still a distinction like Java’s
“int” type vs. “Integer” class. Or maybe it was that they didn’t all
seem to inherit from some base “Object” class. Maybe I’m completely
wrong though. I’d like to know more though.

into a dictionary – in Ruby, I was informed, when it LOOKS like I’m
using a tuple to index into a Hash, in fact the interpreter is working
hard under the covers at forming a string out of that tuple

Actually, that was a misconception, the person who told you that was
later corrected. I think what happens is that the object you’re using
as a hash index simply has its “hash” method called (which all objects
get since it’s defined in Object.

Anyhow, if it isn’t the object-nature of the languages that causes the
speed difference, my guess is that it’s the age, maturity, and
interpreter differences. Python’s interpreter has probably had 5x the
man-hours put into it that Ruby’s has had, so there’s still lots of room
for tweaking improvement. I also think there’s a fundamental difference
in the interpreter, based on the fact you can have .pyc files, and .pyo
files, but there’s no such thing as a .rbc or a .rbo file. But my
knowledge of the internals of either interpreter is basically nonexistant.

You might be surprised. Try coding in standard C or assembly a program
that must work with integers as large as 52!, without using some finely
tuned external library for the pupose, and we’ll see what performance
you do get…;-). [In practice, multiple-precision arithmetic is NOT
trivial to code with decent performance]. Sure, I could use GMP, say –
but then I could use it for Ruby or C just as well, and the variability
becomes unbounded. I am interested in comparing standard languages
as opposed to languages coupled with any one of a zillion potential
add-on libraries, after all.

Ok, but by that same token, if Python’s multiple-precision arithmetic
support has had a lot more work than Ruby’s, it’s bound to be much
faster. If so, it wouldn’t be a big surprise if Python 2.3’s arithmetic
was twice as fast as that of Ruby 1.6. Maybe that’s the cause of the
slowdown. In any case, I wouldn’t get too hung up on it. For the
things I tend to use Ruby for, speed isn’t an issue at all. It has
easily reached the point where it is “fast enough”.

I know of no tasks where “a scripting language” is NOT appropriate,
except operating systems (kernels and drivers), and accelerators for
“scripting languages”

Unfortunately, I do, in particular embedded systems where code size and
memory size is at a premium. With the stuff I’m working on, we’re using
scripting languages where we can, to test, prototype, etc. but in the
end we won’t have any embedded scripting language on the current product.

(Ruby has some very elegant parts, those designed from scratch, but
e.g. all of those $_ $` $’ $! etc etc that it borrowed from Perl
surely can’t be considered elegant…???)…?

No, certainly not. But then again, I have yet to come across a Ruby
program which uses them. In fact, I often argue against including them
in future versions of Ruby, as well as some of the non-oo-like Kernel
methods like “open” and “gsub” which are also Perl cruft.

I’m curious though, how do you know that Ruby has $_, $ and friends? Did you see it in a book, online, in a critique of Ruby, or in code? Like I said, I've never seen them in code, but they're mentioned in books, and always used in critiques of Ruby. To me, criticizing $ in
Ruby is like criticizing C for having Duff’s Device.

I’ll move on to something else – after all Python and Ruby are clearly
both perfectly general-purpose languages, so it’s not as if I’ll soon
run out of application domains to explore, hm?-)

Nope, and it’s fun to hear your reports of your explorations. I don’t
have much time these days to do my own explorations. The only thing I’d
like better is if you’d explore what I find interesting, rather than
what you find interesting… but that’s probably asking a bit too much,
isn’t it? :wink:

Ben

Alex Martelli aleaxit@yahoo.com

Or Python – no “access control” whatsoever, just advisory indications
of what’s meant to be “published” and what’s meant to be for internal use
only. Just the time saved not having to decide what’s private, public,
or protected (Stroustrup regrets having introduced the complication of
that third intermediate classifier – see his book “Design and Evolution
of the C++ programming language”) is by itself a huge performance boost.

If you have actually read D&E, you’d know that I disagree with your
statement. Even if you want to quote me in support of something I
disagree with, you could try to quote accurately. Your statement of my
position on “protected” is highly inaccurate.

  • Bjarne Stroustrup; error

Robert Klemme bob.news@gmx.net skrev den Tue, 16 Sep 2003 05:08:35 +0900:

def fact(n)
@facts[n] ||= (@facts.length…n).inject(@facts.last) {|f, i| @facts[i] =
i * f}
end

And, I think there’s a subtle bug with the inject parameter. Another
version:

def fact(n)
@facts ||= [0,1]
@facts[n] ||= (@facts.length…n).inject(@facts[-1]) {|f, i| @facts[i] = i

  • f}
    end

Can you spell it out for me? I fail to see the difference.

And I wouldn’t do the initial assignment inside the method when
we’re discussing performance…

Regards,

/Robert

why use a constant?

Because it looks better than a global, and exhibits what I consider to be
better behaviour overall.
but a constant is a constant. constants should be used for constant
values, not things that change. i don’t see how a constant behaves any
better than a global in this case. it’s a, what, 100 line script,
globals may pass. to be good style, the whole thing should be kept in
some class somewhere,
nikolai

···


::: name: Nikolai Weibull :: aliases: pcp / lone-star / aka :::
::: born: Chicago, IL USA :: loc atm: Gothenburg, Sweden :::
::: page: www.pcppopper.org :: fun atm: gf,lps,ruby,php,war3 :::
main(){printf(&linux[“\021%six\012\0”],(linux)[“have”]+“fun”-97);}

Mark Wilson wrote:

lol. Aesthetically, I prefer @ to $. One is circular, the other is
serpentine. One represents the spiritual, the other lucre.

Surely you’re jesting? The fine $ symbol is the stylized personal
emblem of Sigismondo Malatesta, the Signore of Rimini (and many other
parts in Romagna, too). It’s an S, for Sigismondo, entwined with a
I, for Isabella, his life-long lover (I believe he did marry her on
her deathbed, actually, so she was his wife for a very short while).

When not totally stylzed, the I is generally depicted as a tree, and
the S a snake climbing the tree – the tree of knowledge in the
garden of Eden, and the snake tempting man to reach for knowledge
of Good and Evil that apparently he was not meant to possess.

BTW, the best place to admire the $ symbol and reflect on its deep
symbolism and long history is of course the Tempio Malatestiano in
Rimini – personally I classify it as the masterpiece of Leon Battista
Alberti, and among the true gems of the Italian Rinascimento revival
of architecture. You’ll see the tree-and-snake painted all over the
place, of course.

Nor do I have anything against serpentine symbolism, mind you (would
anyone expect me to, after all?). I just prefer the $ not to abut
other symbols (such as letters and digits) too directly, whence the
preference for $_foo over $foo.

Aesthetically, I like a little humor in the threads.

I did think of proposing some outrageous joke, such that the “$”
stood for “dollar”, but given the obvious differences between a S
and a d nobody would of course fall for that. You’d almost think
the symbol was chosen by a bunch of freemason freethinkers who
were aware of the Malatestas’ mostly-hidden roles in freemasonry,
Rosicrucianism, and other anti-clerical movements through the
centuries, starting with the Renaissance’s rediscovery of Pagan
classicism. Nah, nobody would ever fall for THAT one, either.

Alex

Bjarne Stroustrup wrote:

If you have actually read D&E, you’d know that I disagree with your
statement. Even if you want to quote me in support of something I
disagree with, you could try to quote accurately. Your statement of my
position on “protected” is highly inaccurate.

This is off-topic, but the obvious question is: “Do you Ruby?”
:wink:

  • Bjarne Stroustrup; error

-Kent

Bjarne Stroustrup wrote:

Alex Martelli aleaxit@yahoo.com

Or Python – no “access control” whatsoever, just advisory indications
of what’s meant to be “published” and what’s meant to be for internal use
only. Just the time saved not having to decide what’s private, public,
or protected (Stroustrup regrets having introduced the complication of
that third intermediate classifier – see his book “Design and Evolution
of the C++ programming language”) is by itself a huge performance boost.

If you have actually read D&E, you’d know that I disagree with your
statement. Even if you want to quote me in support of something I
disagree with, you could try to quote accurately. Your statement of my
position on “protected” is highly inaccurate.

For the benefit of those of us who don’t own that book (though I
do own at least one other) – can you tell us what in fact your
position is on “protected”?

Hal Fulton

I know of no tasks where “a scripting language” is NOT appropriate,
except operating systems (kernels and drivers), and accelerators for
“scripting languages”

Unfortunately, I do, in particular embedded systems where code size and
memory size is at a premium. With the stuff I’m working on, we’re using
scripting languages where we can, to test, prototype, etc. but in the
end we won’t have any embedded scripting language on the current product.

on a sidenote: I remember on of the first embedded linux distribution
(possibly ETLinux) that was base on Tcl. The author of it highlighted
that having a quite fast interpreter with low memory footprint was
acceptable, noted that you could save much more space for the other
programs, cause an interpreted language script is far more ‘dense’
that compiled C or whatever.
(btw, if Ruby 1.8 was used you’ll get the standard unix tools for free
, as in cd,cat,sort,grep…)

what do you think of it ?

“Robert Feldt” feldt@ce.chalmers.se schrieb im Newsbeitrag
news:oprvj614c2oglyup@mail1.telia.com

Robert Klemme bob.news@gmx.net skrev den Tue, 16 Sep 2003 05:08:35
+0900:

def fact(n)
@facts[n] ||= (@facts.length…n).inject(@facts.last) {|f, i|
@facts[i] =
i * f}
end

And, I think there’s a subtle bug with the inject parameter. Another
version:

def fact(n)
@facts ||= [0,1]
@facts[n] ||= (@facts.length…n).inject(@facts[-1]) {|f, i| @facts[i]
= i

  • f}
    end

Can you spell it out for me? I fail to see the difference.

Argh! My fault! I read “@facts.last” as “last index”, but it’s “last
element”. Oh just forget it…

/me scuffles away into some corner and coils up.

And I wouldn’t do the initial assignment inside the method when
we’re discussing performance…

Yeah. I just put it there to ensure proper operation if someone copied
and pasted the code somewhere else.

Regards

robert