Ben Morrow said:
Quoth Rainer Weikusat <
[email protected]>:
[...]
2. The 'Like most ...' statement is wrong: The example code I gave
should be identical to the code in a typical 'getter' method.
That's not the point, though. The interesting question is not 'Are array
derefs faster than hash derefs?': everyone already knows they are. The
interesting questions are 'How much difference would it make to the
overall performance of my application if I switched from hashref to
arrayref objects?' and 'Does that make it worth putting up with the
limitations of arrayref objects?'. My benchmark suggests the answer to
the first is 'maybe 2 or 3%, for an app which is CPU-bound rather than
IO-bound'; and unless the answer to the first was something huge, like a
50x speed increase, my answer to the second would be an unqualified
'No'.
This 'overall performance' idea is too simplistic. Eg, assume the
application is a server whose purpose is to make 'policy descisions'
for HTTP requests, that is, deny or allow them based on 'some
criterion' like 'URL black- or whitelisted' or 'classified as
belonging to a page of content-category ...'. Ideally, 'making the
policy descision shouldn't add any noticeably latency to requests AND
the measurable latency should be so small that it is possible to point
people at the fact that this can't be causing their 'internet
performance problems' even despite they suspect otherwise (which they
are going to do). Also, the descision really shouldn't add any latency
because only one such question can be processed at any given time and
this then becomes a question of 'how many requests can be processed per
second', considering that adding a latency of 1s is WAY too much. In
addition, all of this may need to run on relatively low-spec (that
is, cheap to mass-produce, hardware) and people are going to expect
that it will support at least a couple of thousands of concurrent
users (this is not a contrived example).
Taking this into account, what is more worthwhile? Using
datastructures with minimally faster access times (and less memory
requirements) or 'genuflecting before the god of code bumming', that
is "de-structuring the code" by 'inlining everything which can
conceivably be inlined'. Do I rather put up with the perceived
limitations of the former in order to avoid the latter for as long as
humanly possible, ie, am I willing to make a concsious effort to avoid
wasteing time on stuff where 'wasting time' doesn't buy me anything so
that I can afford to waste time on stuff where it does by me
something?
In line with this reflection, using anonymous arrays also enables
creating objects which retain direct access to their properties
without ad hoc hackery like
use constant NAME => __PACKAGE__.'name';
$h->{+NAME} = ...
because, just like structures in C, arrays provide an ordered set of
slots which means that something like 'use the next five free slots'
is possible which can't be done with hashes in a straight-forward way.
Of course, *if* someone were to produce a system for building arrayref
objects which *didn't* place any limits on their flexibility,
The idea to use anonymous arrays in order to enable 'nested superclass
attributes' is inherently limited to single-inheritance data
inheritance. This implies that everything which can be done in Java
can be done in this way in Perl, too, and even easier because
contortions like 'interfaces' aren't needed. Considering that this
language isn't entirely unused, discarding single-inheritance out of
hand as 'not good enough for me' seems a little preposterous. And -
since Perl isn't a "one size for all and users are fitted to it as
necessary" - the option to use other object representation where it
actually matters is always available.
[...]
To change the subject a little back to something more interesting,
here's a sketch of an idea I was playing with a while ago for a
completely different way of representing attributes.
[...]
package Foo;
use Object::Closures;
BUILD {
my $att = $_[0];
method get_att => sub { $att };
method set_att => sub { $att = $_[0] };
};
sub new { construct @_ }
The most important disadvantages are that it makes method calls even
more expensive,
According to some text I read on the web some
years ago[*], the main problem with this is that every object uses
two additional lexical pads for each of its attributes in this way.
[*] Unfortunately, I can't quote this here because doing so would
seriously upset 'certain people' who prefer keeping their heads firmly
dug into the sand wrt what is or isn't available for free on the
internet (this means they claim that this 'free availability' would
be a serious problems but - for some reason - they don't consider it
worthwhile to do something against it ...).