遍历map和list的速度问题

今天看同事写的代码里有如下的代码:

for(int i =0;i < map_T.count(); i++)
{
T * t = map_T.value(map_T.keys().at(i));
}

我评论到这样速度太慢(其实内容不多,用什么方式遍历用户是感觉不到的)应该用迭代器遍历,结果引起激烈的讨论,同时还讨论到了链表的遍历方法,并且还拿群里给出的数据说明用“下标”遍历链表比用迭代器快。

于是我自己也写了段代码进行测试(测试代码很easy,就不粘贴了),结果显示,map用key去遍历value的速度比直接用迭代器慢了十倍多,因为使用key去访问value时,每一次访问都会引起二分查找,而用迭代器访问时,时间复杂度为O(1)(我没去分析源码,猜的),必然要比用key去一个个索引value快。

而在测试链表时,我突然发现STL中的list根本就没提供下标访问函数,原因是用下标访问的最坏时间复杂度太大,例如当链表长度很大时,要用下标去访问中间的一个结点时,必然要经过很多步的间接访问。

说出了这个情况后,同事说Qt中提供的QList有提供QList<T>::at(int)函数,用于下标访问,并且速度比迭代器快,我不服,不服跑个分呗,于是又进行测试,结果却是,用at函数遍历比用迭代器快了近一倍,不解啊,于是就去分析QList的源代码了,结果发现下面这段代码:

struct Q_CORE_EXPORT QListData {
    struct Data {
        QtPrivate::RefCount ref;
        int alloc, begin, end;
        void *array[1];
    };
    Data *d;
    inline void **at(int i) const { return d->array + d->begin + i; }
    inline void **begin() const { return d->array + d->begin; }

    inline void **end() const { return d->array + d->end; }
  /// .........................
};算是好好上了一课。估计Qt是为了提高速度,使用了连续内存,提高了随机访问的速度,看来不能拿其它库和自己相对熟悉点的STL比啊,毕竟有些库是做了优化的,不能固化自己的知识。
时间: 2024-12-19 23:39:03

遍历map和list的速度问题的相关文章

遍历Map集合四中方法

<embed wmode="transparent" src="http://chabudai.sakura.ne.jp/blogparts/honehoneclock/honehone_clock_tr.swf" quality="high" bgcolor="#ffffff" width="160" height="70" name="honehoneclock&qu

遍历map和list

遍历map 1.这是最常见的并且在大多数情况下也是最可取的遍历方式.在键值都需要时使用. Map<Integer, Integer> map = new HashMap<Integer, Integer>(); for (Map.Entry<Integer, Integer> entry : map.entrySet()) { System.out.println("Key = " + entry.getKey() + ", Value =

数组去重复及记录重复个数(以及遍历map的四种方法)

private static void check(String[] array) { // 字符串数组中,含有不重复的字符串有哪些?每一个重复的个数 Map<String,Integer> map = new HashMap<>(); for(int i=0;i<array.length;i++){ if(map.get(array[i]) != null){ map.put(array[i], map.get(array[i]) + 1);// value + 1 } e

转!! Java中如何遍历Map对象的4种方法

在Java中如何遍历Map对象 How to Iterate Over a Map in Java 在java中遍历Map有不少的方法.我们看一下最常用的方法及其优缺点. 既然java中的所有map都实现了Map接口,以下方法适用于任何map实现(HashMap, TreeMap, LinkedHashMap, Hashtable, 等等) 方法一 在for-each循环中使用entries来遍历 这是最常见的并且在大多数情况下也是最可取的遍历方式.在键值都需要时使用. [java] view

Java遍历Map集合方法

package testMap; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; /**  * 循环遍历Map集合  *   * @author Administrator  *   */ pub

遍历Map集合的几种方式

1 import java.util.HashMap; 2 import java.util.Iterator; 3 import java.util.Map; 4 import java.util.Map.Entry; 5 6 /** 7 * <p>遍历Map集合</p> 8 * @author:[email protected] 9 * @date:2017-5-30 10 */ 11 public class Test { 12 public static void main

Map.Entry遍历Map

Map.entry是Java中的一个接口.每一个Map.entry代表一个map对象. 可以通过 Map是java中的接口,Map.Entry是Map的一个内部接口,它表示map中的一个实体(及一个key-value对). map提供了一些方法如entrySet()返回值entry实体的set集合 Set<Map.Entry<K,V>>:keySet()返回值key的set集合 Set<K> 常用用来遍历map中的key和遍历map中的实体的方法为: Map<St

25.使用Iterator和增强型for循环遍历Map集合

/** * 宠物类,狗狗和企鹅的父类. */ public abstract class Pet { protected String name = "无名氏";// 昵称 protected int health = 100;// 健康值 protected int love = 0;// 亲密度 public abstract void eat(); //抽象方法eat(),负责宠物吃饭功能. /** * 无参构造方法. */ public Pet() { } /** * 有参构造

java 中遍历Map的几种方法

转自: http://blog.csdn.net/wzb56/article/details/7864911 方法分为两类: 一类是基于map的Entry:map.entrySet(); 一类是基于map的key:map.keySet() 而每一类都有两种遍历方式: a.利用迭代器 iterator: b.利用for-each循环: 代码举例如下 package cn.wzb; import java.util.ArrayList; import java.util.HashMap; impor