Hi Eliot,
The reason why I wrote that method was to help Chris speed up his code. Since my only goal was to maximize performance, I didn't care about other things like readability. Using a temporary variable to hold the bits would improve it for sure. I suggested Chris to use a class variable to hold the FloatArray instance. If he can actually do that depends on the level of concurrency he uses. This method is just an optimized version of what Louis LaBrunda posted, so I kept all constant values as they were (they don't seem to be correct though). Inlining #isFinite gives an additional 15% speedup for infinite receivers, and about 2% for finite ones.
Here's another variant with even better performance, especially for infinite receivers:
hashKey32
| bits | self < Infinity ifFalse: [ ^16rFFFFFFFE ]. NegativeInfinity < self ifFalse: [ ^0 ]. bits := ConverterFloatArray at: 1 put: self; basicAt: 1. self < 0.0 ifTrue: [ ^16rFF800000 - bits ]. ^16r80000003 + bits
Levente
On Sun, 21 Dec 2014, Eliot Miranda wrote:
Hi Levente,
please rewrite using a temp to hold the raw bits, a class var to hold the float array and hexadecimal. Then one can understand much easier. Also is inlining isFinite that important for performance?
rawBits := FloatArrayBuffer at: 1 put: self; basicAt: 1 etc...
Eliot (phone hence not writing the full method)
On Dec 20, 2014, at 7:27 PM, Levente Uzonyi leves@elte.hu wrote:
On Sat, 20 Dec 2014, Chris Muller wrote:
On Fri, Dec 19, 2014 at 4:01 PM, Louis LaBrunda Lou@keystone-software.com wrote:
Hi Chris,
Is this any faster?
Float>>#hashKey32
^self isFinite ifTrue: [ self negative ifTrue: [4286578688 - self asIEEE32BitWord] ifFalse: [self asIEEE32BitWord + 2147483651] ] ifFalse: [self negative ifTrue: [0] ifFalse: [4294967294]].
About the same, but I think I like your code better. Thanks.
Dave has already suggested to use a FloatArray for conversion instead of #asIEEE32BitWord. We use this technique in various network protocol implementations, and it works great.
Here's a significantly faster, optimized version:
hashKey32: aFloatArray
self - self = 0.0 ifTrue: [ self < 0.0 ifTrue: [ ^4286578688 - (aFloatArray at: 1 put: self; basicAt: 1) ]. ^2147483651 + (aFloatArray at: 1 put: self; basicAt: 1) ]. self < 0.0 ifTrue: [ ^0 ]. ^4294967294
The argument is any FloatArray instance with at least one slot.
Levente