改进Java代码性能的建议
你好,我这么做只是为了好玩,我想知道是否有更有效/更快的方法来做这件事。对给定的数字和字母列表进行所有可能的组合,然后将它们打印到文本文件中。我目前有这个,并寻求建议改进Java代码性能的建议,java,algorithm,combinations,Java,Algorithm,Combinations,你好,我这么做只是为了好玩,我想知道是否有更有效/更快的方法来做这件事。对给定的数字和字母列表进行所有可能的组合,然后将它们打印到文本文件中。我目前有这个,并寻求建议 import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; public class combos { public static void main(String[] args){ char[] alph
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
public class combos {
public static void main(String[] args){
char[] alphabet = new char[] {'0','1','2','3','4','a','b','c','d','e'};
StringExcersise.possibleStrings(5, alphabet,"");
}
} class StringExcersise {
public static void possibleStrings(int maxLength, char[] alphabet, String curr){
if(curr.length() == maxLength) {
try (PrintWriter out = new PrintWriter(new FileWriter("./Combos.txt", true))) {
out.println(curr);
}catch (IOException e) {
System.err.println(e);}
} else {
for(int i = 0; i < alphabet.length; i++) {
String oldCurr = curr;
curr += alphabet[i];
possibleStrings(maxLength,alphabet,curr);
curr = oldCurr;
}
}
}
}
目前运行大约需要26秒。最后写入文件并用尾部递归替换递归将时间缩短到不到1秒:
public static void main(String[] args)
{
char[] alphabet = new char[]{'0', '1', '2', '3', '4', 'a', 'b', 'c', 'd', 'e'};
Set<String> permutations = new HashSet<>();
possibleStrings(5, alphabet, "", permutations);
try (PrintWriter out = new PrintWriter(new FileWriter("./Combos.txt", true)))
{
out.println(permutations);
}
catch (IOException e)
{
System.err.println(e);
}
}
public static void possibleStrings(int maxLength, char[] alphabet, String curr, Set<String> permutations)
{
if (curr.length() == maxLength)
{
permutations.add(curr);
}
else
{
for (char anAlphabet : alphabet)
{
possibleStrings(maxLength, alphabet, curr + anAlphabet, permutations);
}
}
}
最大的性能瓶颈是IO。每次打开/关闭文件都非常昂贵。我建议你只打开一个。此外,您不需要首先创建集合,因为随着集合的增长,这会变得非常昂贵,只需在计算结果时将结果写入缓冲文件即可 通过构建char[]而不是字符串并打印char[],可以获得相对较小的改进
class StringExercise {
static void possibleStrings(char[] alphabet, PrintWriter pw, char[] curr, int index) {
if (index == curr.length) {
pw.println(curr);
return;
}
for (char c : alphabet) {
curr[index] = c;
possibleStrings(alphabet, pw, curr, index + 1);
}
}
}
public class Combos {
public static void main(String[] args) throws FileNotFoundException {
long start = System.currentTimeMillis();
try (PrintWriter pw = new PrintWriter("combos.txt")) {
StringExercise.possibleStrings("01234abcde".toCharArray(), pw, new char[5], 0);
}
System.out.printf("Took %.3f seconds to run%n", (System.currentTimeMillis()-start)/1e3);
}
}
印刷品
Took 0.030 seconds to run
我检查它是否生成了预期的输出。只是一个想法,但是为什么不将所有可能的值保存在一个静态列表中,并在文件中写入一次,而不是每次都对所有可能的值执行一次呢。I/O操作的成本很高。如果是出于其他目的,则可能会出现这种情况。每次运行它时,我都会使用不同的数字和字母列表。是否有方法使每组数字和字母在输出文件中的新行上?我想您可以在每个字符串值之后追加\n,当它写入文件时,它们将在新行上。