"Bordet, Simone" wrote:
> Hey Ole,
>
> > For the TxCapsule change from collections to arrays: I have to
> > admit that this is ugly compared to the performance gained.
>
> sorry I didn't get, you mean that there was no performance gain ?
> Isn't ArrayList as fast as arrays, and it avoids you the System.arraycopy
> for shrink-enlarge, etc ?
ArrayList is almost as fast as raw arrays. The System.arraycopy()
still happens with ArrayList; it is just hidden in the
implementation of the class.
The performance gain is little and in two places:
- We access the data directly instead of through a wrapper
method (ie. get() and size()).
- We have strong typing in the array, so we avoid doing a
cast with the associated runtime type checking.
> > But it is all hidden in private fields and methods.
> > For the timeout code: The Java collection classes do not have
> > a data structure implementing a priority queue, so I had to
> > write it myself. And by not factoring the priority queue out into
> > a seperate classs, I am able to do timeout cancels in time
> > O(log(n)). Since then I have learned that JavaSoft used the same
> > algorithm in the java.util.Timer code, except they _did_ factor
> > the priority queue out into another class so that individual
> > timers cannot be cancelled in an efficient way.
> > But all of this is hidden in private fields and methods in the
> > org.jboss.util.timeout.TimeoutFactory class.
> > IMHO this hairy algoritm is needed for jBoss to scale well.
>
> Well, got the same problem for the tasks that resize the cache and passivate
> the old beans, and ended up writing a class very similar to java.util.Timer,
> and a priority queue class that is reusable (org.jboss.util.Heap). I'll
> commit it very soon, you may take a look at it and see if it's worth reusing
> in the timeout package.
Such a structure is quite useful, and I wonder why it has never
become part of the library. I will most definitely have a look
at it when you commit it, but I am afraid that it is hard to
get around the problem that prohibited me from factoring out the
priority queue into a seperate class in the first place:
To remove an arbitrary node from the queue in time O(log(n))
you have to know the position of the node in the heap tree, and
since the heap is shuffled on inserts and removals, information
in the node will have to be shuffled along with it. For this I
have a field in the node that contains the node index in the
queue array. Whenever the heap is shuffled, I update this field
to keep it current. Without this field and the cooperation of
the priority queue to keep it updated, I would have to do a linear
search to find the index of the node.
> > For the implementation I care a lot less about ugly code. The
> > code should IMHO be as simple and easily readable as possible
>
> Isn't this caring about the way the code is written :-) ?
Yes. I just don't find it as important as a clean interface.
Making the interface clean and easy to use is IHMO _a lot_
more important than a clean and easy to read implementation.
> > while still doing the needed job with the needed efficiency.
> > But if ugly code in the implementation is needed to get the job
> > done with the needed efficiency, I'll accept ugly code.
>
> Well, bear in mind that the compiler will generate the same bytecode if you
> write
>
> if (array[++getIndex()].function() > 0)
>
> or
>
> int index = getIndex();
> ++index;
> MyObject obj = array[index];
> int result = obj.function();
> if (result > 0)
>
> which is IMHO less ugly than the former. All this will not affect
> performance, but affects very much mantainability of the code.
Agree. Though sometimes I feel tempted to do two things at the
same time like:
int index = getIndex();
MyObject obj = array[++index];
if (obj.function() > 0)
Best Regards,
Ole Husgaard.