Skip to content

Commit

Permalink
Merge pull request #4955 from chimp1984/cache-frequent-method-calls
Browse files Browse the repository at this point in the history
Cache results of isFiatCurrency and isCryptoCurrency
  • Loading branch information
sqrrm authored Dec 16, 2020
2 parents 2532816 + ecad724 commit 4cdd94a
Showing 1 changed file with 56 additions and 23 deletions.
79 changes: 56 additions & 23 deletions core/src/main/java/bisq/core/locale/CurrencyUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Collectors;
Expand All @@ -53,7 +54,6 @@

@Slf4j
public class CurrencyUtil {

public static void setup() {
setBaseCurrencyCode(Config.baseCurrencyNetwork().getCurrencyCode());
}
Expand All @@ -62,6 +62,14 @@ public static void setup() {

private static String baseCurrencyCode = "BTC";

// Calls to isFiatCurrency and isCryptoCurrency are very frequent so we use a cache of the results.
// The main improvement was already achieved with using memoize for the source maps, but
// the caching still reduces performance costs by about 20% for isCryptoCurrency (1752 ms vs 2121 ms) and about 50%
// for isFiatCurrency calls (1777 ms vs 3467 ms).
// See: https://github.com/bisq-network/bisq/pull/4955#issuecomment-745302802
private static final Map<String, Boolean> isFiatCurrencyMap = new ConcurrentHashMap<>();
private static final Map<String, Boolean> isCryptoCurrencyMap = new ConcurrentHashMap<>();

private static Supplier<Map<String, FiatCurrency>> fiatCurrencyMapSupplier = Suppliers.memoize(
CurrencyUtil::createFiatCurrencyMap)::get;
private static Supplier<Map<String, CryptoCurrency>> cryptoCurrencyMapSupplier = Suppliers.memoize(
Expand Down Expand Up @@ -391,12 +399,25 @@ public static List<TradeCurrency> getMatureMarketCurrencies() {
}

public static boolean isFiatCurrency(String currencyCode) {
if (currencyCode != null && isFiatCurrencyMap.containsKey(currencyCode)) {
return isFiatCurrencyMap.get(currencyCode);
}

try {
return currencyCode != null
boolean isFiatCurrency = currencyCode != null
&& !currencyCode.isEmpty()
&& !isCryptoCurrency(currencyCode)
&& Currency.getInstance(currencyCode) != null;

if (currencyCode != null) {
isFiatCurrencyMap.put(currencyCode, isFiatCurrency);
}

return isFiatCurrency;
} catch (Throwable t) {
if (currencyCode != null) {
isFiatCurrencyMap.put(currencyCode, false);
}
return false;
}
}
Expand All @@ -417,28 +438,37 @@ public static Optional<FiatCurrency> getFiatCurrency(String currencyCode) {
* contains 3 entries (CryptoCurrency, Fiat, Undefined).
*/
public static boolean isCryptoCurrency(String currencyCode) {
// Some tests call that method with null values. Should be fixed in the tests but to not break them return false.
if (currencyCode == null)
return false;

// BTC is not part of our assetRegistry so treat it extra here. Other old base currencies (LTC, DOGE, DASH)
// are not supported anymore so we can ignore that case.
if (currencyCode.equals("BTC"))
return true;
if (currencyCode != null && isCryptoCurrencyMap.containsKey(currencyCode)) {
return isCryptoCurrencyMap.get(currencyCode);
}

// If we find the code in our assetRegistry we return true.
// It might be that an asset was removed from the assetsRegistry, we deal with such cases below by checking if
// it is a fiat currency
if (getCryptoCurrency(currencyCode).isPresent())
return true;
boolean isCryptoCurrency;
if (currencyCode == null) {
// Some tests call that method with null values. Should be fixed in the tests but to not break them return false.
isCryptoCurrency = false;
} else if (currencyCode.equals("BTC")) {
// BTC is not part of our assetRegistry so treat it extra here. Other old base currencies (LTC, DOGE, DASH)
// are not supported anymore so we can ignore that case.
isCryptoCurrency = true;
} else if (getCryptoCurrency(currencyCode).isPresent()) {
// If we find the code in our assetRegistry we return true.
// It might be that an asset was removed from the assetsRegistry, we deal with such cases below by checking if
// it is a fiat currency
isCryptoCurrency = true;
} else if (!getFiatCurrency(currencyCode).isPresent()) {
// In case the code is from a removed asset we cross check if there exist a fiat currency with that code,
// if we don't find a fiat currency we treat it as a crypto currency.
isCryptoCurrency = true;
} else {
// If we would have found a fiat currency we return false
isCryptoCurrency = false;
}

// In case the code is from a removed asset we cross check if there exist a fiat currency with that code,
// if we don't find a fiat currency we treat it as a crypto currency.
if (!getFiatCurrency(currencyCode).isPresent())
return true;
if (currencyCode != null) {
isCryptoCurrencyMap.put(currencyCode, isCryptoCurrency);
}

// If we would have found a fiat currency we return false
return false;
return isCryptoCurrency;
}

public static Optional<CryptoCurrency> getCryptoCurrency(String currencyCode) {
Expand Down Expand Up @@ -527,7 +557,9 @@ private static CryptoCurrency assetToCryptoCurrency(Asset asset) {
return new CryptoCurrency(asset.getTickerSymbol(), asset.getName(), asset instanceof Token);
}

private static boolean isNotBsqOrBsqTradingActivated(Asset asset, BaseCurrencyNetwork baseCurrencyNetwork, boolean daoTradingActivated) {
private static boolean isNotBsqOrBsqTradingActivated(Asset asset,
BaseCurrencyNetwork baseCurrencyNetwork,
boolean daoTradingActivated) {
return !(asset instanceof BSQ) ||
daoTradingActivated && assetMatchesNetwork(asset, baseCurrencyNetwork);
}
Expand Down Expand Up @@ -582,7 +614,8 @@ public static Optional<Asset> findAsset(String tickerSymbol, BaseCurrencyNetwork
}

// Excludes all assets which got removed by DAO voting
public static List<CryptoCurrency> getActiveSortedCryptoCurrencies(AssetService assetService, FilterManager filterManager) {
public static List<CryptoCurrency> getActiveSortedCryptoCurrencies(AssetService assetService,
FilterManager filterManager) {
return getAllSortedCryptoCurrencies().stream()
.filter(e -> e.getCode().equals("BSQ") || assetService.isActive(e.getCode()))
.filter(e -> !filterManager.isCurrencyBanned(e.getCode()))
Expand Down

0 comments on commit 4cdd94a

Please sign in to comment.