我有一个程序,只需使用HashSet删除字符数组的重复元素。
这是我的计划:
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class MainClass {
public static void main(String[] arg) {
double sT = System.nanoTime();
Character[] data = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r',
's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd',
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b',
'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z' };
Set<Character > uniqueSet = new HashSet<Character>(Arrays.asList(data));
Character[] strArr = new Character[uniqueSet.size()];
uniqueSet.toArray(strArr);
for(Character str:strArr){
System.out.println(str);
}
System.out.println(System.nanoTime() - sT);
}
}
它提供所需的输出。但问题是执行时间。有没有什么方法可以在我的程序中实现以减少执行时间?
答案 0 :(得分:5)
由于您可以拥有的不同类型的元素非常小,您可以轻松使用简单数组而不是哈希集(类似于设置或计数排序的方法)。如果您只关心非大写英文字母,则声明数组boolean met[26];
,如果您需要能够支持所有字符,请使用boolean met[256];
。
迭代数组,只有在met
值为false时才向结果中添加一个字符。将字符添加到结果时,不要忘记将其标记为已使用。
不涉及散列,因此 - 更好的性能。
编辑:因为看起来有些混淆我的意思我将尝试添加代码示例boolean met[] = new boolean[256]; // Replace 256 with the size of alphabet you are using
List<Character> res = new ArrayList<Character>();
for(Character c:data){
int int_val = (int)c.charValue();
if (!met[int_val]) {
met[int_val] = true;
res.add(c);
}
}
// res holds the answer.
答案 1 :(得分:3)
首先要意识到写入控制台非常昂贵。如果删除
System.out.println(str);
这将大大加快代码速度。
另外需要注意的是,你的代码运行时间不足以预热代码(它不会被编译)你应该运行测试大约2到10秒,看看它需要多长时间热身代码。
所花费的时间
端到端,性能提升2000倍;)
最终代码看起来像
StringBuilder strArr = null;
long sT = 0;
int runs = 1000000;
for (int i = -40000; i < runs; i++) {
if (i == 0)
sT = System.nanoTime();
String text = "qwertyuiopasdfghjklzxcvbnm" +
"qwertyuiopasdfghjklzxcvbnm" +
"qwertyuiopasdfghjklzxcvbnm" +
"qwertyuiopasdfghjklzxcvbnm" +
"qwertyuiopasdfghjklzxcvbnm" +
"qwertyuiopasdfghjklzxcvbnm" +
"qwertyuiopasdfghjklzxcvbnm" +
"qwertyuiopasdfghjklzxcvbnm" +
"qwertyuiopasdfghjklzxcvbnm";
BitSet bs = new BitSet(256);
for (int j = 0, len = text.length(); j < len; j++)
bs.set(text.charAt(j));
strArr = new StringBuilder();
for (int j = -1; (j = bs.nextSetBit(j+1)) >= 0; )
strArr.append((char) j);
}
System.out.printf("Took an average of %,d ns%n", (System.nanoTime() - sT) / runs);
System.out.print(strArr);
打印
Took an average of 1,287 ns
abcdefghijklmnopqrstuvwxyz
答案 2 :(得分:2)
让Google Caliper负责微基准测试:
0% Scenario{vm=java, trial=0, benchmark=Array} 12868.77 ns; σ=523.07 ns @ 10 trials
us
12.9
vm: java
trial: 0
benchmark: Array
12.9微秒。与你的1319微秒不太一样,是:)
供参考,这是确切的代码:
import com.google.caliper.Runner;
import com.google.caliper.SimpleBenchmark;
public class Performance extends SimpleBenchmark {
public int timeArray(int reps) {
int sum = 0;
for (int rep = 0; rep < reps; rep++) {
Character[] data = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i',
'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b',
'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u',
'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'a', 'b', 'c', 'd', 'e',
'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
'y', 'z' };
sum += new HashSet<>(Arrays.asList(data))
.toArray(new Character[new HashSet<Character>
(Arrays.asList(data)).size()]).length;
}
return sum;
}
public static void main(String... args) {
Runner.main(Performance.class, args);
}
}
答案 3 :(得分:0)
您可以使用Google Guava为您执行此操作。关于它有一个Stackoverflow discussion。