【问题标题】:Regarding time consuming calculations in java关于java中耗时的计算
【发布时间】:2023-11-19 16:37:01
【问题描述】:

我正在尝试编写用于从文件夹中读取 120 个文件并对其执行一些计算的代码。当我调试代码时,它工作正常,但是执行时间超过 20 分钟,我知道这可能是由于代码中的错误。但是,有人可以研究它并提出可能的方法来减少执行时间。请让我知道我是否应该提供更多信息。谢谢。

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;

public class myclass {
  static int total = 1;
  static int r = 0;

  public static void main(String[] args) {

    ArrayList<Double> mysignal = new ArrayList<Double>();
    ArrayList<Double> mylist = new ArrayList<Double>();

    double x;
    double a;
    myclass obj = new myclass();
    String target_dir = "path for folder";
    File dir = new File(target_dir);
    File[] files = dir.listFiles();

    for (File f : files) {
      if (f.isFile()) {
        BufferedReader inputStream = null;

        try {
          inputStream = new BufferedReader(new FileReader(f));
          String line;

          while ((line = inputStream.readLine()) != null) {
            System.out.println(line);
            mysignal.add(Double.valueOf(line));
            total++;

          }
        } catch (IOException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }

        a = obj.funtioneg(mysignal, total);
        mylist.add(r, a);
        System.out.println(mylist.get(r));
        r++;

      }
    }
  }

  public double functioneg(ArrayList<Double> s, int N) {

    ArrayList<Double> y = new ArrayList<Double>();
    double sum = 0, a1 = 0;
    double[] o1 = new double[N - 1];// processed signal

    for (int n = 0; n < counter_main - 1; n++) {
      for (int k = 0; k < 40; k++) {

        if (n - k >= 0) {
          a1 = s.get(n - k);
          sum = sum + (a1 * a1);// energy

        } else
          sum = sum + 0;
      }

      o1[n] = sum;

      sum = 0;

    }
    double sum1 = 0;
    double avg;
    for (int t = 0; t < counter_main - 1; t++) {

      sum1 = sum1 + o1[t];
    }

    avg = sum1 / N - 1;

    return (avg);
  }
}

【问题讨论】:

  • 您尝试解析多少个文件,这些文件有多大?如果您尝试仅使用几个文件执行此操作,会发生什么情况。还慢吗?
  • 我认为这个问题可能更适合代码审查网站codereview.stackexchange.com
  • @idipous,120 个文件,每个文件大小约为 14KB
  • 在代码审查时询问,当你这样做时,请解释你正在尝试做什么,这样我们就不必对你的代码进行逆向工程:输入是什么样的,你做了什么计算正在表演。
  • @200_success 谢谢,也贴在code review上,其实这几天很苦恼,得把计算出来的数据再写一个txt文件。

标签: java eclipse bufferedreader filereader


【解决方案1】:

你需要关闭你的InputStream

读取目录中的每个文件后(在您​​的try - catch 块之后)编写语句:

inputStream.close();

【讨论】:

  • 我添加了该声明,谢谢。但是,执行时间不受影响。
【解决方案2】:

正如 andrewdleach 所指出的,您应该关闭输入流。

此外,您可能还想尝试 Java 8 函数 Files#walk(参见 question)以更有效地遍历文件。

【讨论】:

    【解决方案3】:

    首先尝试注释掉该行:

    System.out.println(line);
    

    到控制台的输出很慢(我的意思是真的很慢),这一行基本上是将每个处理过的文件的内容复制到控制台。

    除此之外,您还可以尝试累积在 functioneq() 方法和/或其部分(例如使用 System.nanoTime())中花费的时间,以找到最耗时的部分(或在调试器下运行)并使用采样分析,这是最简单的分析方法并且非常有效 - 只需反复暂停程序并查看它最常暂停的位置)。

    【讨论】:

    • 感谢您的回复。我删除了打印语句,但是,它仍然需要时间。实际上,每个文件包含大约 2000 个数字,这些数字正在函数中进行处理。
    • 顺便说一句。变量 counter_main 的(通常)值是多少?我没有在发布的代码中看到它声明/设置...