It seems there is a lot of agreement on the details....
However, one key point i tried to make, which i'm not sure has
come across as clear as i wished, is that there is no choice in being
thread safe or not:
A program that is not thread safe is an INCORRECT program.
Whatever speed&memory performance gain it has it still is a broken
program, it CAN FAIL AT ANY TIME.
As a consequence any optimization must be designed while
maintaining thread-safety: Nobody wins when your program is broken,
even though it may seem to work most of the time!!!
Luckily, in Java the designer's kit for doing that includes many
tools:
final fields, volatile fields, immutable objects, thread
confinement synchronized, Lock, Semaphore, Atomic* data, etc.
etc.
Then, I think you have an issue with the design of the BigInteger
class in complaining about it being hard to use efficiently to
implement more complex algorithms, like typically used in
cryptography. Especially since the class invites to use its nice suite
of build in operations all geared for crypto computations. That has
been, i'm sure a deliberate design choice: It gives you the basic
functionality to build a correct program. And, that is a correct
program in the complete sense i mentioned above.
In that design choice optimization in time and space have been
left to the programmer/user: to you and in general to the implementors
of Crypto Service Provider packages.
One other design choice made for the BigInteger class is to use
methods to specify operations. An alternative would have been to use
Objects. That may be a good way to about to embed your optimizations
in. It allows you to specify parameter setting methods that either
take a BigInteger or a Wnaf (or Wmof) representations. And similarly
result getters that can take the result in any of the supported
representations.:
class Operation {
setParam1( X one) { ... }
setParam1( Y one) { ... )
setParam2( X two) { ... }
... /* more parameter setters as needed*/
X getXresult(){ ... }
Y getYresult(){ ... }
}
With all the X and Y classes as immutable value classes that copy
their value upon request and initialize the value by copying the
initial value specified in the constructor.
Internally Operation can do whatever it wants, use any internal
representation that is fit for purpose, including one that is internal
to one of X or Y.
In this structure you can get thread safety and
performance.
However, one specific thread safety issue to consider here is
that the result may be requested by another thread before it is
available. You could specify that null is returned in that case, so
that the client thread can decide to try again later. Or you could add
a fancy method to check if the result is ready and even put clients in
a queue in that call so they can wait.
Good luck with your experiments
At 05:35 -0500 16-10-2007, Michael Hall wrote:
On Oct 16, 2007, at 2:46 AM, Eduard de
Jong wrote:
BigInteger and all the immutable value classes are intended for
sharing values amongst objects which may live in several threads and
perform actions on the value unknown to the designer of the value
class. The use of BigInteger is one very convenient way to safely
share the result of a computation.
Is one convenient way that I agree is good for a _final_ value.
However, that it is an inefficient way to represent a _interim_ value
for it's normal computational usage still remains at least part of my
premise. I think actual usage should probably take precedence in
design. I have no problem with the end result of a calculation ending
up in a immutable value wrapper. But BigInteger is different from
other Number subclasses like Integer in that it doesn't just wrap a
value, it is used in actual computations more like a primitive.
Integer has no methods for this purpose. Immutable isn't suited to
this usage and is a bad design choice for it.
One good workaround as you pointed out that applied to my example is
to get away from immutable during a local computation where the
interim results are generated. You might always be able to use this
approach and avoid the problems associated with immutable interim
results resulting in a lot of dead memory. Although, since java
doesn't provide a separate mutable class you have to write the to
mutable workarounds yourself.
So, what I'm doing basically has two
purposes. Explore a little some of the alternative optimization
algorithms in java that apply to Elliptic Curve Cryptography and see
what they actually seem to do when performance profiled for both speed
and memory. Again I'm hoping to find Win/Win situations. The second
purpose is demonstrate the idea that BigInteger has design problems
that get problematic in highly iterative computational code to the
point that avoiding it's use in some cases is a good optimization
without even any algorithm changes involved.
I take your point that it is a good general design approach to ensure
safe threading where thread safety is more a concern than performance.
But, getting away from the general, if performance is more important
to your specific case then forcing the code to be thread safe to the
detriment of performance is a bad decision. In BigInteger's case there
doesn't seem to be a lot of awareness of this. So maybe I am still
wrong, my testing is still somewhat limited. But, so far does suggest
that BigInteger as immutable wastes memory and I'm still assuming,
although I'm not claiming to have proved this, as a side-effect to
memory issues it suffers in performance.
Mike
Hall hallmike at att dot
net
--
Eduard de Jong
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Java-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/java-dev/email@hidden
This email sent to email@hidden