Оптимизация / параллелизм JAVA: чтение CSV-файла, анализ данных для удвоения и последующий расчет значений - PullRequest
2 голосов
/ 21 октября 2011

Я работаю над программой анализа данных на Java. Данные взяты с автомобильных датчиков и передаются в формате CSV. Он должен быть прочитан, проанализирован, чтобы удвоиться, а затем «преобразован» (скажем, от значения 5/12 Вольт до силы G / миль / ч /% открытия дроссельной заслонки /% силы торможения и т. Д.). Размер файла данных будет около 200 МБ.

В настоящее время я читаю данные с помощью BufferedReader, разделяя токен с помощью indexOf () и substring (), анализируя их как удвоенные с помощью parseDouble, добавляя их в ArrayList из ArrayLists с двойными значениями (по одному ArrayList для каждого токен, максимум около 20 токенов). После того, как составлены массивы, мне нужно преобразовать двойные числа, что означает использование полиномов для каждого значения (кажется, что оно занимает большую часть времени, более 2/3 от него).

Вся последовательность составляет около 7 секунд для выборочных данных из 240 000 строк с 20 токенами. Мне интересно, как я могу улучшить это. Я думал об использовании потоков и параллелизма для чтения и анализа файлов, но, похоже, самая большая проблема - это полиномиальная математика. Код, который я использую для вычисления преобразованных значений:

pol0 + pol1 * value + pol2 * Math.pow(value, 2) + pol3 * Math.pow(value, 3)
         + pol4 * Math.pow(value, 4);

где polX - это полиномы, а значение - двойное значение, которое я конвертирую. Это, конечно, отличается в зависимости от того, сколько полиномов у меня есть.

Итак, имеет ли это смысл? И если да, какие-либо предложения о том, как улучшить производительность этого процесса?

Спасибо за отличный сайт со многими полезными пользователями. : -)

Ответы [ 2 ]

2 голосов
/ 21 октября 2011

Math.pow(value, 2) довольно дорого.Это использует log + exp.Вместо этого вы можете использовать обычное умножение, которое намного быстрее.

double value2 = value * value;
double value3 = value * value2;
double value4 = value2 * value2;
double p = pol0 + pol1 * value + pol2 * value2 + pol3 * value3
     + pol4 * value4;

Другой подход заключается в умножении с ходом

double p = (((pol4 * value + pol3) * value + pol2) * value + pol1) * value + pol0;

ArrayLists из double - это дорогая структуранакладные расходы).Он в несколько раз больше двойного [].

например

double[] buffer = new double[1024];
List<double[]> list = new ArrayList<>():
while((line = ....) {
  int used = 0;
  // found a double
  buffer[used++] = Double.parseDouble();
  double[] doubles = new double[used];
  System.arraycopy(buffer,0,doubles,0,used);
  list.add(doubles);
}
0 голосов
/ 21 октября 2011

Существует более эффективный метод для вычисления полинома:

double r = pol4;
r = value*r + pol3;
r = value*r + pol2;
r = value*r + pol1;
r = value*r + pol0;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...