Java - самый быстрый способ перебрать список <Map>и сравнить содержимое карты с известными данными - PullRequest
0 голосов
/ 27 мая 2018

У меня есть небольшой Java-класс, который будет запускаться на сервере облачных приложений, поэтому он должен выполняться как можно быстрее.

Что мне нужно сделать, так это перебрать List<Map>, получитьсодержимое текущего Map, а затем сделать некоторую логику на нем.Map содержит строки и двойные числа.

Это моя текущая реализация:

for (int i = 0; i < count; i++) {

  Map data = result.get(i);
  double priceToCheck = Double.parseDouble(data.get("value").toString());
  String criteria = data.get("criteria").toString();
  String coin = data.get("coin").toString();


  if (coin.equals("BTC")) {
    if (criteria.equals("above")) {
      if (BTC > priceToCheck) {
        // create notficaition
        sendNotification = true;

      }
    } else {
      if (BTC < priceToCheck) {
        // create notification
        sendNotification = true;
      }
    }
  } else if (coin.equals("BCH")) {
    if (criteria.equals("above")) {
      if (BCH > priceToCheck) {
        // create notficaition
        sendNotification = true;
      }
    } else {
      if (BCH < priceToCheck) {
        // create notification
        sendNotification = true;
      }
    }
  } else if (coin.equals("ETH")) {
    if (criteria.equals("above")) {
      if (ETH > priceToCheck) {
        // create notficaition
        sendNotification = true;
      }
    } else {
      if (ETH < priceToCheck) {
        // create notification
        sendNotification = true;
      }
    }
  } else if (coin.equals("ETC")) {
    if (criteria.equals("above")) {
      if (ETC > priceToCheck) {
        // create notficaition
        sendNotification = true;
      }
    } else {
      if (ETC < priceToCheck) {
        // create notification
        sendNotification = true;
      }
    }
  } else if (coin.equals("LTC")) {
    if (criteria.equals("above")) {
      if (LTC > priceToCheck) {
        // create notficaition
        sendNotification = true;
      }
    } else {
      if (LTC < priceToCheck) {
        // create notification
        sendNotification = true;
      }
    }
  } else if (coin.equals("XRP")) {
    if (criteria.equals("above")) {
      if (XRP > priceToCheck) {
        // create notficaition
        sendNotification = true;
      }
    } else {
      if (XRP < priceToCheck) {
        // create notification
        sendNotification = true;
      }
    }

  }

Где result это List<Map>, "BTC" это строка и BTCявляется двойным

Как вы можете видеть наивысший уровень, если операторы проверяют строку coin, есть шесть возможных значений.Как только coin найден, я определяю значение criteria, а затем сравниваю двойные числа в зависимости от значения criteria

. Мне кажется, что это очень громоздкий способ достижения этой цели.задача, это работает, но это относительно медленно.Я не могу придумать способ ускорить его без непосредственного доступа к каждому элементу Map и проверки содержимого вручную.

У кого-нибудь еще есть идеи?

Ответы [ 2 ]

0 голосов
/ 27 мая 2018

Есть одна оптимизация, которая действительно выделяется здесь.Ваш оригинальный фрагмент кода будет перебирать весь ваш список, чтобы скорректировать ваш sendNotification логический.

Если вы установите sendNotification все, что вам нужно сделать, вы можете стратегически поместить break в каждое из ваших условных выражений.Это приведет к короткому замыканию цикла после желаемого поведения.В худшем случае вы бы перебрали весь список.

for (int i = 0; i < count; i++) {


  if (coin.equals("BTC")) {
    if (criteria.equals("above")) {
      if (BTC > priceToCheck) {
        // create notficaition
        sendNotification = true;
        break; // exits the loop

      }
    } else {
      if (BTC < priceToCheck) {
        // create notification
        sendNotification = true;
        break;
      }
   }
  } else if (coin.equals("BCH")) {
    if (criteria.equals("above")) {
      if (BCH > priceToCheck) {
        // create notficaition
        sendNotification = true;
        break;
      }
0 голосов
/ 27 мая 2018

У меня есть небольшой класс Java, который будет запускаться на сервере облачных приложений, поэтому он должен выполняться как можно быстрее.

Прежде всего, есть некоторые предположениятам это сомнительно.

  1. Да, приятно, что ваш код работает так быстро, насколько это возможно, но в большинстве случаев в этом нет необходимости.И, в частности, тот факт, что вы работаете на облачном сервере, не обязательно делает его необходимым.

  2. Вы полагаете, что ваше приложение работает недостаточно быстро.(Вы тестировали?)

  3. Вы предполагаете, что эта часть кода (или будет) ответственна за слишком медленный код.(Вы реализовали это? Вы профилировали это?)

И это:

Мне кажется, что это очень громоздкий способ выполнения этой задачи, это работает, но это относительно медленно.

Громоздкие и медленные не одно и то же.Часто громоздкий многословный / неуклюжий * на 1027 * быстрее , чем сжатый / элегантный.


Так что теперь к 1032 * потенциальным проблемам с производительностью вашего кода.(Помните, что все это может не иметь отношения к вашим ошибочным предположениям!)

  1. Если поля известны / могут быть известны во время компиляции, лучше использовать пользовательский класс, чемMap.Метод Map::get будет на несколько порядков медленнее, чем метод получения в пользовательском классе, и карта обычно будет использовать на порядок больше памяти.

    Пользовательский класс также позволит вам использовать примитивные типы,и так далее, вместо того, чтобы вводить значения в String.Отказ от этого также принесет выигрыш в производительности.

  2. Это медленно:

    double priceToCheck = Double.parseDouble(data.get("value").toString());
    

    Вы, похоже, принимаете double (или Double) , converting it to a string and then converting it back to a double`.Преобразования между числами и десятичными строками относительно дороги.

  3. Если во время компиляции известны значения coin и criteria, рассмотрите возможность использования enum или booleanчем строкаСравнение будет быстрее, и вы сможете использовать оператор switch ... или простой if в логическом случае.

Фактически, итерация черезСписок является одним из аспектов, где это не так много возможностей для оптимизации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...