I know this is a really old thread, but i am writing an app (incidentally a trading app), in which computation of the indicators like MACD (which computes multiple exponential moving averages) over several thousand ticks of historical candlesticks was taking an unacceptable amount of time (several minutes). I was using BigDecimal.
every time i scrolled or resized the window, it would have to just iterate through the cached values to resize the Y scale, but even that would take several seconds to update. it made the app unusable. every time i would tweak the parameters for various indicators, it would take several minutes again to recompute.
then i switched it all to double and it's sooooo much faster. the problem was that i cache values using a hashmap. the solution i came up with uses a pool of wrappers for the double values. by pooling the wrappers, you don't take the performance hit of autoboxing to/from Double.
the app now calculates MACD (+MACD signal, MACD histogram) instantly with no lag. it's amazing how expensive BigDecimal object creation was. think about something like a.add( b.multiply( c )).scale(3) and how many objects that one statement creates.
import java.util.HashMap;
public class FastDoubleMap<K>
{
private static final Pool<Wrapper> POOL = new Pool<FastDoubleMap.Wrapper>()
{
protected Wrapper newInstance()
{
return new Wrapper();
}
};
private final HashMap<K, Wrapper> mMap;
public FastDoubleMap()
{
mMap = new HashMap<>();
}
public void put( K pKey, double pValue )
{
Wrapper lWrapper = POOL.checkOut();
lWrapper.mValue = pValue;
mMap.put( pKey, lWrapper );
}
public double get( K pKey )
{
Wrapper lWrapper = mMap.get( pKey );
if( lWrapper == null )
{
return Double.NaN;
}
else
{
return lWrapper.mValue;
}
}
public double remove( K pKey )
{
Wrapper lWrapper = mMap.remove( pKey );
if( lWrapper != null )
{
double lDouble = lWrapper.mDouble;
POOL.checkIn( lWrapper );
return lDouble;
}
else
{
return Double.NaN;
}
}
private static class Wrapper
implements Pooled
{
private double mValue ;
public void cleanup()
{
mValue = Double.NaN;
}
}
}
b
? Unlessb
is special, the codeONE.divide(b)
will crash. So you're leaving out a few details from your question. – Holub