爪哇 - 将字符串转换为加倍的最有效方法(Java - Most efficient way to

2019-10-17 18:34发布

嗨,我从一个文本文件读取和保存每行(用逗号分开)到一个数组。 唯一的问题是,大多数所述阵列中的元件是作为在那里的两个元件是字符串双精度值。 作为这样的结果,我不得不使阵列的String []数组。 由于这个原因,每当我想在数组中的双值执行了一些公式,我得先分析他们的双重价值。 我从字面上运行这些方程的1000+迭代,因此我的代码在不断解析字符串成一个双。 这是正在放缓我的节目一个昂贵的方式。 有没有更好的办法,我可以从字符串数组值转换为双精度值或是否有更好的方法保存来自文本文件中的行,当我应该采取? 谢谢

以下是该阵列中的一个看起来像我已经从文本文件中读取后:

String[] details = {"24.9", "100.0", "19.2" , "82.0", "Harry", "Smith", "45.0"};

我现在需要乘以第一2种元素,并添加到第3,第4和第7要素的总和。 换句话说我只使用的数字元素(被ofcourse保存为字符串)

double score = (Double.parseDouble(details[0]) * Double.parseDouble(details[1])) + Double.parseDouble(details[2]) + Double.parseDouble(details[3]) + Double.parseDouble(details[6]);

我要在文本文件(超过1000行)每一行做到这一点。 作为这样的结果我的程序运行速度非常慢。 有没有更好的办法,我可以将字符串值转换为双? 或者是有没有更好的办法,我应该去了解它们存储在首位?

编辑:我已经使用分析器来检查该代码的一部分是最慢的,它确实是我在上面所示的代码

Answer 1:

这里是产生像你描述的这10000线长的一个输入文件,然后在回读,做您发布的计算和打印结果到stdout的例子。 我为了得到最糟糕的读取性能读取文件时,明确禁止任何缓冲。 我也没有做任何缓存所有的,因为其他建议。 整个过程,包括生成该文件,执行计算,和打印结果,始终需要大约520-550毫秒。 这是很难的“慢”,除非你重复成百上千的文件的同一过程。 如果从此看到完全不同的表现,那么也许这是一个硬件问题。 发生故障的硬盘可以下降读取性能到几乎为零。

import java.io.*;
import java.util.Random;

public class ReadingDoublesFromFileEfficiency {
    private static Random random = new Random();

    public static void main(String[] args) throws IOException {
        long start = System.currentTimeMillis();
        String filePath = createInputFile();
        BufferedReader reader = new BufferedReader(new FileReader(filePath), 1);
        String line;
        while ((line = reader.readLine()) != null) {
            String[] details = line.split(",");
            double score = (Double.parseDouble(details[0]) * Double.parseDouble(details[1])) + Double.parseDouble(details[2]) + Double.parseDouble(details[3]) + Double.parseDouble(details[6]);
            System.out.println(score);
        }
        reader.close();
        long elapsed = System.currentTimeMillis() - start;
        System.out.println("Took " + elapsed + " ms");
    }

    private static String createInputFile() throws IOException {
        File file = File.createTempFile("testbed", null);
        PrintWriter writer = new PrintWriter(new FileWriter(file));
        for (int i = 0; i < 10000; i++) {
            writer.println(randomLine());
        }
        writer.close();
        return file.getAbsolutePath();
    }

    private static String randomLine() {
        return String.format("%f,%f,%f,%f,%s,%s,%f",
                score(), score(), score(), score(), name(), name(), score());
    }

    private static String name() {
        String name = "";
        for (int i = 0; i < 10; i++) {
            name += (char) (random.nextInt(26) + 97);
        }
        return name;
    }

    private static double score() {
        return random.nextDouble() * 100;
    }
}


Answer 2:

你会做的更好在创建合适的对象,并存储的值 - 这给你两大好处:1)你的代码会因为你避免不必要的重复计算的双精度值更快,2)你的代码会更清楚,因为场将被命名,而不是让这样的方法调用details[0]它是完全不清楚[0]指的是。

由于2)我不知道是什么领域应该是,所以很明显你的类将有所不同,但这个想法是一样的:

public class PersonScore {
    private double[] multipliers = new double[2];
    private double[] summers = new double[3];
    private String first;
    private String last;

    // expects a parsed CSV String
    public PersonScore(String[] arr) {
        if(arr.length != 7)
            throw new InvalidArgumentException("Must pass exactly 7 fields");
        multipliers[0] = Double.parseDouble(arr[0]);
        multipliers[1] = Double.parseDouble(arr[1]);
        summers[0] = Double.parseDouble(arr[2]);
        summers[0] = Double.parseDouble(arr[3]);
        summers[0] = Double.parseDouble(arr[6]);
        first = arr[4];
        last = arr[5];
    }

    public double score() {
        double ret = 1;
        for(double mult : multipliers)
            ret *= mult;
        for(double sum : summers)
            ret += sum;
        return ret;
    }

    public String toString() {
        return first+" "+last+": "+score();
    }
}

请注意,有一个额外的好处,该评分法是目前更为强劲。 你的实现上述硬编码,我们想利用领域,但是通过分析和存储等领域为结构的内容,我们可以实现一个更具可读性,更具扩展性的分数计算方法。



文章来源: Java - Most efficient way to convert string to double