Skip to content

Commit

Permalink
Do sorting on non UI thread as its slow and only attach
Browse files Browse the repository at this point in the history
it to table in UI thread afterwards.

Chain updateSelectedTradeStatistics and updateChartData calls.
  • Loading branch information
chimp1984 committed Nov 4, 2021
1 parent 74ce66c commit 45a40ab
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 86 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@

import lombok.Getter;

import static bisq.desktop.main.market.trades.TradesChartsViewModel.MAX_TICKS;

public class ChartCalculations {
static final ZoneId ZONE_ID = ZoneId.systemDefault();

Expand Down Expand Up @@ -169,7 +171,7 @@ static Map<Long, Pair<Date, Set<TradeStatistics3>>> getItemsPerInterval(List<Tra
// Generate date range and create sets for all ticks
Map<Long, Pair<Date, Set<TradeStatistics3>>> itemsPerInterval = new HashMap<>();
Date time = new Date();
for (long i = TradesChartsViewModel.MAX_TICKS + 1; i >= 0; --i) {
for (long i = MAX_TICKS + 1; i >= 0; --i) {
Pair<Date, Set<TradeStatistics3>> pair = new Pair<>((Date) time.clone(), new HashSet<>());
itemsPerInterval.put(i, pair);
// We adjust the time for the next iteration
Expand All @@ -179,7 +181,7 @@ static Map<Long, Pair<Date, Set<TradeStatistics3>>> getItemsPerInterval(List<Tra

// Get all entries for the defined time interval
tradeStatisticsByCurrency.forEach(tradeStatistics -> {
for (long i = TradesChartsViewModel.MAX_TICKS; i > 0; --i) {
for (long i = MAX_TICKS; i > 0; --i) {
Pair<Date, Set<TradeStatistics3>> pair = itemsPerInterval.get(i);
if (tradeStatistics.getDate().after(pair.getKey())) {
pair.getValue().add(tradeStatistics);
Expand Down Expand Up @@ -292,7 +294,7 @@ static CandleData getCandleData(long tick, Set<TradeStatistics3> set,
}

static long getTimeFromTickIndex(long tick, Map<Long, Pair<Date, Set<TradeStatistics3>>> itemsPerInterval) {
if (tick > TradesChartsViewModel.MAX_TICKS + 1 ||
if (tick > MAX_TICKS + 1 ||
itemsPerInterval.get(tick) == null) {
return 0;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,11 @@
import java.util.Date;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import org.jetbrains.annotations.NotNull;

import static bisq.desktop.main.market.trades.TradesChartsViewModel.MAX_TICKS;
import static bisq.desktop.util.FormBuilder.addTopLabelAutocompleteComboBox;
import static bisq.desktop.util.FormBuilder.getTopLabelWithVBox;

Expand Down Expand Up @@ -162,8 +162,7 @@ private CurrencyListItem specialShowAllItem() {
private SingleSelectionModel<Tab> tabPaneSelectionModel;

private TableColumn<TradeStatistics3ListItem, TradeStatistics3ListItem> priceColumn, volumeColumn, marketColumn;
private final ObservableList<TradeStatistics3ListItem> listItems = FXCollections.observableArrayList();
private final SortedList<TradeStatistics3ListItem> sortedList = new SortedList<>(listItems);
private SortedList<TradeStatistics3ListItem> sortedList = new SortedList<>(FXCollections.observableArrayList());

private ChangeListener<Toggle> timeUnitChangeListener;
private ChangeListener<Number> priceAxisYWidthListener;
Expand Down Expand Up @@ -287,8 +286,6 @@ public void initialize() {

@Override
protected void activate() {
long ts = System.currentTimeMillis();
// root.getParent() is null at initialize
tabPaneSelectionModel = GUIUtil.getParentOfType(root, JFXTabPane.class).getSelectionModel();
selectedTabIndexListener = (observable, oldValue, newValue) -> model.setSelectedTabIndex((int) newValue);
model.setSelectedTabIndex(tabPaneSelectionModel.getSelectedIndex());
Expand Down Expand Up @@ -328,8 +325,6 @@ else if (model.getSelectedCurrencyListItem().isPresent())
currencySelectionSubscriber = currencySelectionBinding.subscribe((observable, oldValue, newValue) -> {
});

sortedList.comparatorProperty().bind(tableView.comparatorProperty());

boolean useAnimations = model.preferences.isUseAnimations();
priceChart.setAnimated(useAnimations);
volumeChart.setAnimated(useAnimations);
Expand All @@ -341,7 +336,6 @@ else if (model.getSelectedCurrencyListItem().isPresent())
nrOfTradeStatisticsLabel.setText(Res.get("market.trades.nrOfTrades", model.tradeStatisticsByCurrency.size()));

exportLink.setOnAction(e -> exportToCsv());
UserThread.runAfter(this::updateChartData, 100, TimeUnit.MILLISECONDS);

if (root.getParent() instanceof Pane) {
rootParent = (Pane) root.getParent();
Expand All @@ -359,11 +353,7 @@ else if (model.getSelectedCurrencyListItem().isPresent())
user.requestPersistence();
});

tableView.setItems(sortedList);
fillList();
layout();

log.error("activate took {} ms", System.currentTimeMillis() - ts);
}

@Override
Expand Down Expand Up @@ -407,15 +397,20 @@ private void fillList() {
.map(tradeStatistics -> new TradeStatistics3ListItem(tradeStatistics,
coinFormatter,
model.showAllTradeCurrenciesProperty.get()))
.collect(Collectors.toList());
}).whenComplete((items, throwable) -> {
log.error("Creating listItems took {} ms", System.currentTimeMillis() - ts);
.collect(Collectors.toCollection(FXCollections::observableArrayList));
}).whenComplete((listItems, throwable) -> {
log.debug("Creating listItems took {} ms", System.currentTimeMillis() - ts);

long ts2 = System.currentTimeMillis();
listItems.setAll(items);
// Is slow because of sorting of > 100k items. But at least it seems it works on the thread from the
// CompletableFuture callback, so we do not block the UI thread;.
log.error("Applying sorted list took {} ms",
System.currentTimeMillis() - ts2);
sortedList.comparatorProperty().unbind();
// Sorting is slow as we have > 100k items. So we prefer to do it on the non UI thread.
sortedList = new SortedList<>(listItems);
sortedList.comparatorProperty().bind(tableView.comparatorProperty());
log.debug("Created sorted list took {} ms", System.currentTimeMillis() - ts2);
UserThread.execute(() -> {
// When we attach the list to the table we need to be on the UI thread.
tableView.setItems(sortedList);
});
});
}

Expand Down Expand Up @@ -473,7 +468,7 @@ private void exportToCsv() {
private void createCharts() {
priceSeries = new XYChart.Series<>();

priceAxisX = new NumberAxis(0, TradesChartsViewModel.MAX_TICKS + 1, 1);
priceAxisX = new NumberAxis(0, MAX_TICKS + 1, 1);
priceAxisX.setTickUnit(4);
priceAxisX.setMinorTickCount(4);
priceAxisX.setMinorTickVisible(true);
Expand Down Expand Up @@ -539,11 +534,11 @@ public Number fromString(String string) {

priceChartPane.getChildren().add(priceChart);

volumeAxisX = new NumberAxis(0, TradesChartsViewModel.MAX_TICKS + 1, 1);
volumeAxisX = new NumberAxis(0, MAX_TICKS + 1, 1);
volumeAxisY = new NumberAxis();
volumeChart = getVolumeChart(volumeAxisX, volumeAxisY, volumeSeries, "BTC");

volumeInUsdAxisX = new NumberAxis(0, TradesChartsViewModel.MAX_TICKS + 1, 1);
volumeInUsdAxisX = new NumberAxis(0, MAX_TICKS + 1, 1);
NumberAxis volumeInUsdAxisY = new NumberAxis();
volumeInUsdChart = getVolumeChart(volumeInUsdAxisX, volumeInUsdAxisY, volumeInUsdSeries, "USD");
volumeInUsdChart.setVisible(false);
Expand Down Expand Up @@ -650,7 +645,7 @@ public String toString(Number object) {
long index = MathUtils.doubleToLong((double) object);
// The last tick is on the chart edge, it is not well spaced with
// the previous tick and interferes with its label.
if (TradesChartsViewModel.MAX_TICKS + 1 == index) return "";
if (MAX_TICKS + 1 == index) return "";

long time = model.getTimeFromTickIndex(index);
String fmt = "";
Expand Down
Loading

0 comments on commit 45a40ab

Please sign in to comment.