最近在csdn搜索了关于EntrySet与KeySet的效率问题,发现很多说entrySet快,但是都是好几年前的,而且看他给的源码跟我点开jdk的源码不一致应该是jdk版本不同,另外也有说自己测试结果发现keySet快的,那么到底如何呢?还是得自己验证一下。
我用的是jdk1.8测试的,代码如下
/**
* 测试Map的keySet和entrySet的性能
*
* @author yangbiao
* @date 2021/1/13 15:31
*/
public class Test {
HashMap<String,String> map;
@BeforeEach
void setUp() {
map = new HashMap<>();
for(int i = 0; i <= 1000000; i++){
map.put("key-" + i, "value-" + i);
}
}
@org.junit.jupiter.api.Test
void testKeySet() {
StringBuilder sb = new StringBuilder();
long startTime = System.currentTimeMillis();
for( String s : map.keySet()){
sb.append(s).append(map.get(s));
}
long kTime = System.currentTimeMillis() - startTime;
System.out.println("字符串长度:"+sb.length());
System.out.println("keySet花费: " + kTime);
}
@org.junit.jupiter.api.Test
void testEntrySet() {
StringBuilder sb = new StringBuilder();
long startTime = System.currentTimeMillis();
for( Map.Entry<String, String> e : map.entrySet()){
//将map的key和value进行拼接
sb.append(e.getKey()).append(e.getValue());
}
long eTime = System.currentTimeMillis() - startTime;
System.out.println("字符串长度:"+sb.length());
System.out.println("entrySet花费: " + eTime);
}
@org.junit.jupiter.api.Test
void testTogether() {
System.out.println("先测试keySet再测试entrySet");
testKeySet();
testEntrySet();
}
@org.junit.jupiter.api.Test
void testTogetherAgain() {
System.out.println("先测试entrySet再测试keySet");
testEntrySet();
testKeySet();
}
@org.junit.jupiter.api.Test
void testTogetherBy2Thread() throws InterruptedException {
//创建两个线程分别测试
Thread thread1 = new Thread(this::testKeySet);
Thread thread2 = new Thread(this::testEntrySet);
thread1.start();
thread2.start();
Thread.sleep(4000);
}
@org.junit.jupiter.api.Test
void testTogetherBy2ThreadAgain() throws InterruptedException {
//创建两个线程分别测试
Thread thread1 = new Thread(this::testEntrySet);
Thread thread2 = new Thread(this::testKeySet);
thread1.start();
thread2.start();
Thread.sleep(4000);
}
}
定义一个HashMap
,每个测试方法都初始化一次,有6个测试方法,分别是测试keySet,entrySet,keySet+entrySet,entrySet+keySet,keySet+entrySet两个线程执行,entrySet+keySet两个线程执行。
为什么要这样写测试方法,因为我发现网上给的很多测试是在同一个方法里进行测试的,我就交换了下顺序,发现结果竟然是后面的总是慢于前面的。这或许是java编译器优化了?我也不清楚。单个方法进行测试结果会有误差不好判断,所以方法1和2的结果都没有参考性可言。
运行方法3和4即testTogether()
跟testTogetherAgain()
是截然相反的结果。
运行方法5和6即testTogetherBy2Thread()
跟testTogetherBy2ThreadAgain()
,用两个线程不同加入顺序执行测试。
表明entrySet略快于keySet,再增加一倍的数据,测试如下
证明entrySet快于keySet。