Can you please post the code you used to produce the results you mention?
Further comments inline...

On Mon, Jun 24, 2013 at 11:46 AM, Darryl L. Pierce <>wrote:

> On Thursday, Rafi and I had a discussion in IRC about how to maintain
> the AMQP type information after retrieving a value from a
> Qpid::Proton::Data object.
> With Ruby < 2.0.0 we can using meta-programming to create an instance
> attribute on Fixnum, Bignum, etc. With a performance hit (Fixnum is an
> immediate value in Ruby even though there's a "class" for it) of just
> under 100% [1] we can store and fetch the type information from a
> Fixnum.
> With Ruby 2.0.0, though, this is all unavailable. Fixnum and similar
> classes are all frozen, blocking us from performing this sort of duck
> typing to the class.
> Extending classes, unfortunately, results in even worse performance.
> I experimented with adding a new class that extends Numeric (you can't
> extended frozen classes) that would maintain only the AMQP type info and
> defer all numeric operations to an instance of Fixnum resulted in
> performance increases up of nearly 2,000% (from ~161.5 ms to over 3,200
> ms) due to the creation of new objects for each of those operations.
> Bottom line, I'm struggling to come up with an idea for how to maintain
> the AMQP type information outside of the Data type properly.
> Thoughts? Ideas?
> [1] Output from running a simple Ruby script to compare a raw Fixnum to
> a duck typed Fixnum that tracks the AMQP type reports the following:
> Simple Fixnum:
> value is an instance of Fixnum
> Time: 161.481438 ms
> new_foo = 10000000
> Modified Fixnum:
> foo=1 (proton_type is YO!)
> value is an instance of Fixnum
> Time: 306.556147 ms
> new_foo=10000000 (and it's type = )
> Fixnum with it's Proton info removed:
> value is an instance of Fixnum
> Time: 307.510454 ms
> new_foo=10000000 (type=)
> The script simply takes a value and then increments by 1 until it's
> 1,000,000. To do this with a pure Fixnum takes ~161.5 ms. With a
> modified Fixnum that performs the addition and then sets the result to
> have a Proton type value for itself takes ~306.6 ms to do the same. Not
> quite doubling the time even.

I think you need to make your benchmark run through more iterations. In my
own testing, the exact same benchmark run with enough iterations to take on
the order of a minute or so yields significantly different percentages than
one that takes only a few seconds, and ones that take on the order of
milliseconds are almost meaningless as there is too much constant time

> The duck typing doesn't do this to all Fixnum instances, but can be
> applied to returned values from Qpid::Proton::Data so as not to pollute
> the global Fixnum type.

What do you mean by "the duck typing". Assuming I'm guessing correctly at
what you're describing, I would think both these approaches make use of
duck typing in different ways. Duck typing is just the use of implicit
interfaces. Monkey patching core ruby classes to adhere to an implicit
interface that Data uses to extract AMQP type information is one example of
using duck typing. Defining our own numeric classes that implement the
implicit numeric interfaces defined by the core language is also an example
of using duck typing. To which are you referring above? Posting the code
for the different approaches you're describing would help make things more


Reply via email to