优化/并发JAVA:读取CSV文件,解析数据以加倍,然后对值进行计算

时间:2011-10-21 13:24:50

标签: java performance csv concurrency arraylist

我正在研究Java中的数据分析程序。数据来自汽车传感器,并以CSV格式提供。它需要读取,解析为双倍然后“转换”(例如从5/12伏特值到G力/ mph /%节气门开度/%制动力等)。数据文件的大小最多约为200MB。

我目前正在做的是使用BufferedReader读取数据,使用indexOf()和substring()拆分tokenz,使用parseDouble将它们解析为double,将它们添加到具有双精度的ArrayLists的ArrayList(每个都有一个ArrayList)令牌,最多约20个令牌)。在制作arraylists之后,我必须转换双打,这意味着在每个值上使用多项式(这似乎占据了大部分时间,超过了它的2/3)。

对于具有20个令牌的240,000行的样本数据,整个序列约为7秒。我想知道如何改善这一点。我一直在考虑使用流和并发来进行文件读取和解析,但似乎最大的问题是多项式数学。我用来计算转换值的代码是:

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

其中polX是多项式,值是我正在转换的双值。这当然是不同的,这取决于我有多少个多项式。

那么,这有什么意义吗?如果是的话,有关如何改善此流程性能的任何建议吗?

感谢您有一个很棒的网站,有很多有用的用户。 : - )

2 个答案:

答案 0 :(得分:2)

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;

double的ArrayLists是一种昂贵的结构(主要是开销)。它比double []大几倍。

e.g。

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);
}

答案 1 :(得分:0)

有一种更有效的多项式计算方法:

double r = pol4;
r = value*r + pol3;
r = value*r + pol2;
r = value*r + pol1;
r = value*r + pol0;