您的位置:首页 > 编程语言 > Java开发

java性能优化读书笔记之三《程序优化===集合优化(list)》

2015-12-22 14:10 591 查看
说明:本文内容是针对于java集合的性能优化

1. 数据结构

请参考博客数据结构

2. List接口

概述

List是java重要结构之一, 它们的类图如下:



ArrayList和Vector是基于数组数据机构实现的。内部的操作都是对数组进行插入、删除,修改,遍历。可以说ArrayList和Vector是一个可扩容的动态数组。ArrayList与Vector不同之处在于Vector是线程安全的。

LinkList是基于双向链表数据结构实现的。内部的操作是对链表的节点(node)进行插入、删除、修改遍历。

结构图(数组)



结构图(链表)



3. 使用场景

LinkList在元素添加、删除效率比arrayList高,arrayList删除的元素越靠前,效率越低。

arryList在元素查询比LinkList高

4. 源码分析

无参的构造函数

代码清单:

/**
* Constructs an empty list with the specified initial capacity.
*
* @param   initialCapacity   the initial capacity of the list
* @exception IllegalArgumentException if the specified initial capacity
*            is negative
*/
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity];
}

/**
* Constructs an empty list with an initial capacity of ten.
*/
public ArrayList() {
this(10);
}


从源码中获悉,arrayList默认的初始化容器大小为10。

add方法

代码清单

/**
* Appends the specified element to the end of this list.
*
* @param e element to be appended to this list
* @return <tt>true</tt> (as specified by {@link Collection#add})
*/
public boolean add(E e) {
//调用此方法,判断容器是否需要扩容
ensureCapacity(size + 1);  // Increments modCount!!
//新元素赋值到指定的位置(size++)
elementData[size++] = e;
return true;
}

/**
* Increases the capacity of this <tt>ArrayList</tt> instance, if
* necessary, to ensure that it can hold at least the number of elements
* specified by the minimum capacity argument.
*
* @param   minCapacity   the desired minimum capacity
*/
public void ensureCapacity(int minCapacity) {
modCount++;
//获取容器的容量
int oldCapacity = elementData.length;
//判断容器所需的最小容量是否大于本身的容器大小
if (minCapacity > oldCapacity) {
Object oldData[] = elementData;
//容器扩容后的容量
int newCapacity = (oldCapacity * 3)/2 + 1;
//容器扩容后的容量小于容器所需的最小容量。则使用容器所需的最小容量。反之不需要
if (newCapacity < minCapacity)
newCapacity = minCapacity;
// minCapacity is usually close to size, so this is a win:
//数组复制(之后的调用,大家自己看)
elementData = Arrays.copyOf(elementData, newCapacity);
}
}


从源码中获取当容器所需的最小容量大于本身的容器大小。需要进行容器容量扩容。扩容的大小计算法则为
(oldCapacity * 3)/2 + 1


linkList就不讲了

5. List优化点

list容器在添加、删除频繁操作时,请使用linkList。list容器在遍历元素频繁操作时,请使用arrayList。具体场景具体分析

在特定的场景清楚list容器的容量,自己给定list容器的容量。不要使用默认的容器的容量(默认的大小为10)。这样做好处在于避免由于默认的容器容量比较小。导致list容器的容量频繁的扩容。(一般减少代码的运行,就能提高程序性能)

arrayList和linkList性能比较

package org.com.program.data;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* arrayList 添加的性能低于linkedList(在一定数据量),指定arrayList容量,添加的性能高于linkedList
* arrayList 查询的效率大幅度高于linkedList
* arrayList 删除元素越靠前,效率越低。linkedList没有变化
* @author Administrator
*
*/

public class List01 {
private List<Object> arrayList = null;
private List<Object> linkedList = null;
private long startTime;
private long endTime;

@Before
public void listAdd() {
arrayList = new ArrayList<Object>();

//#######arrayList 与linkedList添加功能性能比较
startTime = System.currentTimeMillis();
for(int i=0; i<5000000; i++) {
arrayList.add(i);
}

endTime = System.currentTimeMillis();
System.out.println("arrayList to add  time{}:"+(endTime-startTime));

linkedList = new LinkedList<Object>();

startTime = System.currentTimeMillis();
for(int i=0; i<5000000; i++) {
linkedList.add(i);
}

endTime = System.currentTimeMillis();
System.out.println("linkedList to add time{}:"+(endTime-startTime));
}

@Test
public void listQuery() {

//#######arrayList 与linkedList查询功能性能比较
startTime = System.currentTimeMillis();
for(int i=0; i<50000; i++) {
arrayList.get(i);
}
endTime = System.currentTimeMillis();
System.out.println("arrayList to query time{}:"+(endTime-startTime));

//#######arrayList 与linkedList查询功能性能比较
startTime = System.currentTimeMillis();
for(int i=0; i<50000; i++) {
linkedList.get(i);
}
endTime = System.currentTimeMillis();
System.out.println("linkedList to query time{}:"+(endTime-startTime));

}

@After
public void listDel() {

//#######arrayList 与linkedList删除功能性能比较
startTime = System.currentTimeMillis();
arrayList.remove(0);

endTime = System.currentTimeMillis();
System.out.println("arrayList to del  time{}:"+(endTime-startTime));

startTime = System.currentTimeMillis();

linkedList.remove(0);

endTime = System.currentTimeMillis();
System.out.println("linkedList to del time{}:"+(endTime-startTime));
}
}


arrayList和linkList性能比较===》性能结果



给定arrayList容量大小与默认的arrayList容器大小性能比较

package org.com.program.data;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;
/**
* 给定arrayList容量大小与默认的arrayList容器容量大小性能比较
* @author Administrator
*
*/

public class List03 {

private List<Object> arrayList = null;
private long startTime =0L;
private long endTime = 0L;

//默认arrayList容器容量(10)
@Test
public void defaultCapacity() {
arrayList = new ArrayList<Object>();

startTime = System.currentTimeMillis();
for(int i=0; i<5000000; i++) {
arrayList.add(i);
}

endTime = System.currentTimeMillis();
System.out.println("arryList default capacity to add time{}:"+(endTime-startTime));
}

//指定arrayList容器容量(5000000)
@Test
public void specifiedCapacity() {
arrayList = new ArrayList<Object>(5000000);

startTime = System.currentTimeMillis();
for(int i=0; i<5000000; i++) {
arrayList.add(i);
}

endTime = System.currentTimeMillis();
System.out.println("arryList specified capacity to add time{}:"+(endTime-startTime));
}
}


给定arrayList容量大小与默认的arrayList容器大小性能结果

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  性能优化