Fix quadratic time bug in AveragePriceUtil.getUSDAverage

Now that the trade statistics are retrieved as a sorted set, it can be
assumed that the USD & BSQ trade lists passed to 'getUSDAverage' are
already sorted. Use this to avoid repeatedly scanning the USD trade list
for the first trade dated after each given BSQ trade, by moving two
cursors in a single pass across the respective lists simultaneously.
This commit is contained in:
Steven Barclay 2023-05-06 18:52:11 +01:00
parent b417e36a28
commit 0ba2e491ca
No known key found for this signature in database
GPG Key ID: 9FED6BF1176D500B

View File

@ -34,7 +34,6 @@ import com.google.common.primitives.Doubles;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Comparator;
import java.util.Date; import java.util.Date;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
import java.util.List; import java.util.List;
@ -115,21 +114,23 @@ public class AveragePriceUtil {
return averagePrice; return averagePrice;
} }
private static long getUSDAverage(List<TradeStatistics3> bsqList, List<TradeStatistics3> usdList) { private static long getUSDAverage(List<TradeStatistics3> sortedBsqList, List<TradeStatistics3> sortedUsdList) {
// Use next USD/BTC print as price to calculate BSQ/USD rate // Use next USD/BTC print as price to calculate BSQ/USD rate
// Store each trade as amount of USD and amount of BSQ traded // Store each trade as amount of USD and amount of BSQ traded
List<Tuple2<Double, Double>> usdBsqList = new ArrayList<>(bsqList.size()); List<Tuple2<Double, Double>> usdBsqList = new ArrayList<>(sortedBsqList.size());
usdList.sort(Comparator.comparing(TradeStatistics3::getDateAsLong));
var usdBTCPrice = 10000d; // Default to 10000 USD per BTC if there is no USD feed at all var usdBTCPrice = 10000d; // Default to 10000 USD per BTC if there is no USD feed at all
for (TradeStatistics3 item : bsqList) { int i = 0;
for (TradeStatistics3 item : sortedBsqList) {
// Find usd price for trade item // Find usd price for trade item
usdBTCPrice = usdList.stream() for (; i < sortedUsdList.size(); i++) {
.filter(usd -> usd.getDateAsLong() > item.getDateAsLong()) TradeStatistics3 usd = sortedUsdList.get(i);
.map(usd -> MathUtils.scaleDownByPowerOf10((double) usd.getTradePrice().getValue(), if (usd.getDateAsLong() > item.getDateAsLong()) {
Fiat.SMALLEST_UNIT_EXPONENT)) usdBTCPrice = MathUtils.scaleDownByPowerOf10((double) usd.getTradePrice().getValue(),
.findFirst() Fiat.SMALLEST_UNIT_EXPONENT);
.orElse(usdBTCPrice); break;
}
}
var bsqAmount = MathUtils.scaleDownByPowerOf10((double) item.getTradeVolume().getValue(), var bsqAmount = MathUtils.scaleDownByPowerOf10((double) item.getTradeVolume().getValue(),
Altcoin.SMALLEST_UNIT_EXPONENT); Altcoin.SMALLEST_UNIT_EXPONENT);
var btcAmount = MathUtils.scaleDownByPowerOf10((double) item.getTradeAmount().getValue(), var btcAmount = MathUtils.scaleDownByPowerOf10((double) item.getTradeAmount().getValue(),