On Tue, 05 Aug 2008 17:27:54 -0700, Tom <Th********@earthlink.netwrote:
Hey Pete --
Hey Tom! :)
Seriously though...I don't disagree with the _philosophical_ points you've
made. However, I see the implications differently, at least to some
extent, and I do think your conclusions are at least a little off. I'll
try to touch on just a few points:
[...]
What happens when one has >>
1.20000001 % 0.01
In the above case the 0.00000001 remainder might be very important?
Nope. If you are using a value such as 0.00000001 as your threshold for
"essentially zero", then if you started with a value of "1.20000001",
that's considered, by definition, equal to 1.2.
You do have to pick the correct epsilon for your application, but once
you've done so, there are no worries such as the above. If the difference
between 1.20000001 and 1.2 is significant, then 0.00000001 is too large an
epsilon for your application, by definition.
So checks against the RHS value of 0.01 are not a good practice. In
this case the multiplier would need to be 100,000,000 and
Int32.MaxValue = 2,147,483,647 issues start to emerge.
Eventually even the 128 bit decimal representation fails to provide
sufficient accuracy. Irrational numbers such as 1/3'rd and Pi are not
accurately represented even with decimal utilization. I think it false
to make statements such as: "Usage of decimal type assures
_sufficient_ accuracy."
All of that is true. But it's also true if you are converting floating
point to integer for the purpose of the calculation. Doing that doesn't
avoid those problems.
[...]
2) If you see float % float or double % double in code ... become
very concerned.
No question. I'm just saying that the answer isn't necessarily to change
the code to convert to ints and back again. Such code could be less
readable, and/or more bug-prone (different kinds of overflow
possibilities, for example).
The fact is, I think if one finds oneself doing the remainder operation on
floating point values, it's possible that there's a more fundamental
problem. For example, one is probably using floating point when a
different type would be more appropriate (e.g. decimal, as Jon suggested
in this case).
Fixing a theoretical performance problem is always a bad idea anyway.
Make sure it's a _real_ performance problem before you fix it. But beyond
that, one can become distracted by the performance problem (the trees),
and fail to see a more significant design/correctness problem (the forest).
Yes, if you see a floating point remainder calculation, that's cause for
concern. But I don't think that rewriting the code to improve the
computational performance is really what one ought to be focusing on.
-----------------------------------------------
My observed speed enhancement converting to integers was associated
with huge stock data files where the data was fully loaded into ram to
avoid hard drive i/o speed issues.
Did that data fit entirely into the CPU cache?
If not, then you're still dealing with serious memory i/o problems (as I
mentioned before), and any _computational_ speedup (being just part of the
total performance cost) converting to integer calculations is unlikely to
be nearly as significant as the simple test I did might suggest.
[...]
Once values such as 987.125 were converted to 987125 the rewritten
program ran in approximately 1/5'th the time as the program using
doubles for data storage.
Assuming the _only_ change was from using floating point to integers, a 5x
improvement doesn't sound possible given my test.
Now, if you were converting to Int32 from double, per your example, _that_
would be significant. After all, it would have halved the size of your
data, resulting in much less memory i/o and better cache performance.
That _in conjunction with_ the less-than-2x computational improvement
might have accounted for a 5x improvement.
But note that converting from double to int is actually wrong, as those
are not the same sized storage or precision. You run the risk of
overflowing your ints. Or conversely, you could have just been using
floats and enjoyed the same memory bandwidth improvements that switching
from a 64-bit to 32-bit storage would have regardless.
I was thrilled to have results in 12 minutes
vs 1 hour. Situations where such improvements can be had are rare ...
Indeed they are. Like I said, your suggestion isn't completely useless.
I just think in the vast majority of cases, it's a premature optimization.
Pete