Java基础(二)- 普通for循环、foreach性能比较
最近公司有一个需求,只展示被删除数据的删除时间,删除时间对应updateTime字段。测试环境对应表的数据量在40万+,所以研究下普通for循环与foreach循环的性能比较。
以下测试用例中:集合使用的是ArrayList
测试用例1:
//对应的实体类: class Country { private String name; private long area; private String updateTime; private int isDelete;//0:未删除 1:删除 public Country(String name, long area, String updateTime, int isDelete) { this.name = name; this.area = area; this.updateTime = updateTime; this.isDelete = isDelete; } public String getName() { return name; } public void setName(String name) { this.name = name; } public long getArea() { return area; } public void setArea(long area) { this.area = area; } public String getUpdateTime() { return updateTime; } public void setUpdateTime(String updateTime) { this.updateTime = updateTime; } public int getIsDelete() { return isDelete; } public void setIsDelete(int isDelete) { this.isDelete = isDelete; } }
如果isDelete=0,那么将updateTime置为null;
public class ForLoopTest { private List<Country> list = new ArrayList<>(); public List<Country> listCountries(int count) { int isDelete = ((int) (10 * Math.random())) % 2; for (int i = 0; i < count; i++) { Country country = new Country(i + "", i, i + "", isDelete); list.add(country); } return list; } /** * @Description: 普通for循环 */ public long normalForLoop(List<Country> list) { long start = System.currentTimeMillis(); for (int i = 0; i < list.size(); i++) { if (list.get(i).getIsDelete() == 0) { list.get(i).setUpdateTime(null); } } long end = System.currentTimeMillis(); return end - start; } /** * @Description: foreach循环 */ public long forEachLoop(List<Country> list) { long start = System.currentTimeMillis(); for (Country country : list) { if(country.getIsDelete()==0){ country.setUpdateTime(null); } } long end = System.currentTimeMillis(); return end - start; } public void start() { List<Country> listCountries = listCountries(400000); long l = normalForLoop(listCountries); long l1 = forEachLoop(listCountries); System.out.println("普通for循环时间:" + l); System.out.println("foreach循环时间:" + l1); } public static void main(String[] args) { new ForLoopTest().start(); } }
40万数据量测试结果:
400万数据量测试结果:
发现两者在业务中没有很大的性能差异,后来查询了多个博客的测试用例,如下:
public class ForLoopTest { private List<Country> list = new ArrayList<>(); public List<Country> listCountries(int count) { int isDelete = ((int) (10 * Math.random())) % 2; for (int i = 0; i < count; i++) { Country country = new Country(i + "", i, i + "", isDelete); list.add(country); } return list; } /** * @Description: 普通for循环 */ public long normalForLoop(List<Country> list) { long start = System.currentTimeMillis(); for (int i = 0; i < list.size(); i++) { list.get(i); } long end = System.currentTimeMillis(); return end - start; } /** * @Description: foreach循环 */ public long forEachLoop(List<Country> list) { long start = System.currentTimeMillis(); for (Country country : list) { } long end = System.currentTimeMillis(); return end - start; } public void start() { List<Country> listCountries = listCountries(4000000); long l = normalForLoop(listCountries); long l1 = forEachLoop(listCountries); System.out.println("普通for循环时间:" + l); System.out.println("foreach循环时间:" + l1); } public static void main(String[] args) { new ForLoopTest().start(); } }
普通for循环中调用list的get方法,foreach循环的循环体中没有代码;
40万数据量测试结果如下:
400万数据量测试结果如下:
很明显,普通for循环性能优于foreach循环
总结:基于列表为ArrayList,如果只考虑循环获取list中的数据,那么普通for循环优于foreach循环;如果在循环中需要进行逻辑判断,那么两者性能相差不大