近期在做图像处理的时候。发现某一段代码很的慢。慢得让人无法接受。基本的代码是顺序訪问一个LinkedList的元素,效果是随着index的变大,速度越来越慢,list的元素个数在百万以上。找到原因,分享出来。也希望大家不要跳入同一个陷阱。

还是那一句话。可执行的代码和高质量的代码之间还是有比較远的距离。

LinkedList错误使用方法演示样例

代码里面增加了一些打印时间相关的代码,主要是为了直观的显示执行的耗时。

错误代码

public static void main(String[] args) {
// add elements
int size = 2000000;
List<String> list = new LinkedList<String>();
for (int i = 0; i < size; i++) {
list.add("Just some test data");
} long startTime = System.currentTimeMillis();
for (int i = 0; i < size; i++) {
list.get(i); if (i % 10000 == 0) {
System.out.println("query 10000 elements spend: "
+ (System.currentTimeMillis() - startTime));
startTime = System.currentTimeMillis();
}
}
}

控制台输出例如以下:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQva2lteWxyb25n/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">

错误原因

错误的代码就是list.get(i),LinkedList的底层是一个链表,随机訪问i的时候。链表仅仅能从头往后数,第i个才返回。所以时间随着i的变大时间会越来越长。

正确使用方法

顺序訪问,LinkedList绝对不要用get方法,即使LinkedList的元素个数仅仅有非常少的几个。

养成好习惯,免得犯错。

for each

for (String element : list) {
// process element here
}

iterator

Iterator<String> iter = list.iterator();
while (iter.hasNext()) {
String element = iter.next();
// process element here
}

直接换为ArrayList

public static void main(String[] args) {
// add elements
int size = 2000000;
List<String> list = new ArrayList<String>();
for (int i = 0; i < size; i++) {
list.add("Just some test data");
} long startTime = System.currentTimeMillis();
for (int i = 0; i < size; i++) {
list.get(i); if (i % 10000 == 0) {
System.out.println("query 10000 elements spend: "
+ (System.currentTimeMillis() - startTime));
startTime = System.currentTimeMillis();
}
}
}

ArrayList的控制台输出例如以下:

LinkedList VS ArrayList

以下比較一下LinkedList和ArrayList的效率。

新增、查询、删除比較

ArrayList測试代码例如以下:

public static void main(String[] args) {
// add elements
int size = 20000000;
List<String> list = new ArrayList<String>();
long startTime = System.currentTimeMillis();
for (int i = 0; i < size; i++) {
list.add("Just some test data");
}
System.out.println("add " + size + " elements spend: "
+ (System.currentTimeMillis() - startTime)); // query
startTime = System.currentTimeMillis();
String median = list.get(size / 2);
System.out.println("query median spend: "
+ (System.currentTimeMillis() - startTime)); // delete
startTime = System.currentTimeMillis();
list.remove(median);
System.out.println("delete median spend: "
+ (System.currentTimeMillis() - startTime));
}

LinkedList測试代码例如以下:

public static void main(String[] args) {
// add elements
int size = 20000000;
List<String> list = new LinkedList<String>();
long startTime = System.currentTimeMillis();
for (int i = 0; i < size; i++) {
list.add("Just some test data");
}
System.out.println("add " + size + " elements spend: "
+ (System.currentTimeMillis() - startTime)); // query
startTime = System.currentTimeMillis();
String median = list.get(size / 2);
System.out.println("query median spend: "
+ (System.currentTimeMillis() - startTime)); // delete
startTime = System.currentTimeMillis();
list.remove(median);
System.out.println("delete median spend: "
+ (System.currentTimeMillis() - startTime));
}

各自特点

  • 新增

    ArrayList比LinkedList快非常多,超过一个数量级。

    非常是意外。

  • 随机查询

    在i值非常大的时候,ArrayList比LinkedList快非常多,i越大,差距越大。ArrayList底层是数组。随机訪问时间效率是O(0),而LinkedList是O(n)。

  • 删除

    LinkedList比ArrayList快非常多。LinkedList的删除操作时间效率为O(0)。而ArrayList是O(n),ArrayList须要查找数据、移动数据,所以慢。

总结

尽量使用ArrayList,ArrayList满足不了需求的时候再用LinkedList。依据LinkedList的特点,在以下几种情况下才使用LinkedList。

  • 须要使用java.util.List接口之外的API

    LinkedList实现了Queue和Stack等接口,能够用来当作一些特殊的容器。吐槽JDK里面LinkedList的设计,塞太多东西了,和名字不符。
  • 元素删除比較频繁

    假设数据量大,删除频繁,仅仅能用LinkedList。

  • 内存碎片化且元素非常多

    ArrayList底层是一个数组,数组要求一段连续的内存快。LinkedList也能够充分利用内存的一些碎片。特别是JVM使用Concurrent Mark-Sweep Collector垃圾回收器的时候,显得尤为重要。

LinkedList的一种错误使用方法的更多相关文章

  1. vs------各种错误解决方法

    错误:命名空间System.Net中不存在类型或命名空间名“Http”,或工程里面“引用”的文件太少 转载:http://www.asp.net/mvc/mvc4 错误:LD.exe 已退出,代码为- ...

  2. Modbus通讯错误检测方法

    标准的Modbus串行网络采用两种错误检测方法.奇偶校验对每个字符都可用,帧检测(LRC和CRC)应用于整个消息.它们都是在消息发送前由主设备产生的,从设备在接收过程中检测每个字符和整个消息帧. 用户 ...

  3. 笔记:php有那几种错误提示和查错方法

    php有哪几种错误提示 1.notice : 注意 2.waring : 警告 3.error : 错误 PHP中都有哪几种查错方法? 1.语法检查--php配置文件里,把错误显示选项都打开或者代码开 ...

  4. mysql Access denied for user root@localhost错误解决方法总结(转)

    mysql Access denied for user root@localhost错误解决方法总结(转) mysql Access denied for user \'root\'@\'local ...

  5. ArrayList和LinkedList的几种循环遍历方式及性能对比分析(转)

    主要介绍ArrayList和LinkedList这两种list的五种循环遍历方式,各种方式的性能测试对比,根据ArrayList和LinkedList的源码实现分析性能结果,总结结论. 通过本文你可以 ...

  6. ArrayList和LinkedList的几种循环遍历方式及性能对比分析

    最新最准确内容建议直接访问原文:ArrayList和LinkedList的几种循环遍历方式及性能对比分析 主要介绍ArrayList和LinkedList这两种list的五种循环遍历方式,各种方式的性 ...

  7. JAVA常见错误处理方法 和 JVM内存结构

    OutOfMemoryError在开发过程中是司空见惯的,遇到这个错误,新手程序员都知道从两个方面入手来解决:一是排查程序是否有BUG导致内存泄漏:二是调整JVM启动参数增大内存.OutOfMemor ...

  8. eWebeditor编辑器上传图片路径错误解决方法[疑难杂症]【转,作者:unvs】

    做了一个多版本的网站,后台用的编辑器是eWebeditor,NET版,后面发现上传图片或者文件之后,路径错误无法显示,必须手工修改才行.. 为了更清楚的说明问题,我下面会说的比较详细,首先是网站文件框 ...

  9. ArrayList和LinkedList的几种循环遍历方式及性能对比分析(转载)

    原文地址: http://www.trinea.cn/android/arraylist-linkedlist-loop-performance/ 原文地址: http://www.trinea.cn ...

随机推荐

  1. 模仿.Net ThreadPool的线程池控件

    http://www.2ccc.com/btdown.asp?articleid=5953 ftp://download:S3cirpYW3DoR@www.2ccc.com/vcl/system/20 ...

  2. 【shiro】2.spring整合shiro,注解控制shiro用户/角色/权限And/OR,没有权限跳转到固定页面

    这几天粗浅的把shiro整合到spring中,并且注解控制shiro用户/角色/权限And/OR 步骤: 1.首先maven搭建web项目 2.创建数据库 user/role/authority 其中 ...

  3. IntelliJ IDEA的几种常见的快捷键

    在编写代码的时候直接输入psv就会看到一个psvm的提示,此时点击tab键一个main方法就写好了. psvm 也就是public static void main的首字母. 依次还有在方法体内键入f ...

  4. java中copy 一个list集合的方法

    java将一个list里的数据转移到另外一个list,可以使用for语句,一次使用add方法,示例如下: ArrayList list1=new ArrayList(); list1.add(&quo ...

  5. 12.线程通信CyclicBarrier

    CountDownLatch 监听某个线程的初始化,等待初始化执行完毕后,通知主线程工作.延迟.阻塞的是主线程,在单个线程中. CyclicBarrier 针对多个线程.线程池,多个线程初始化准备之后 ...

  6. SQLAlchemy使用笔记--SQLAlchemy ORM(二)

    參考: http://docs.sqlalchemy.org/en/rel_1_0/orm/tutorial.html#building-a-relationship http://docs.sqla ...

  7. Linux中线程使用详解

    线程与进程为什么有了进程的概念后,还要再引入线程呢?使用多线程到底有哪些好处?什么的系统应该选用多线程?我们首先必须回答这些问题. 使用多线程的理由之一是和进程相比,它是一种非常"节俭&qu ...

  8. NormalMap 贴图 【转】

    转载: http://www.zwqxin.com/archives/shaderglsl/review-normal-map-bump-map.html   说起Normal Map(法线贴图),就 ...

  9. 大气散射 Aerial Perspective

    http://mathinfo.univ-reims.fr/IMG/pdf/PreethamSig2003CourseNotes.pdf https://blog.csdn.net/toughbro/ ...

  10. Java自定义注解Annotation详解

    注解相当于一种标记,在程序中加了注解就等于为程序打上了某种标记,没加,则等于没有某种标记,以后,javac编译器,开发工具和其他程序可以用反射来了解你的类及各种元素上有无何种标记,看你有什么标记,就去 ...