应用中如何使用适当的数据结构

应用中如何使用适当的数据结构

键查找 Searching for a key

选择适当的数据结构是一件大家都认同,却很少有人会考虑的事。从我的经验来看, 这不仅是因为它很难引起人们的好奇心,更重要的原因是它需要不厌其烦的进行实验和基准测试,这可能会增加很多不必要的负担。让我们来举个例子。我在日常工作中遇到的很多软件操作都是查找一个key然后对其进行操作,要么检查它是否存在, 要么取出与其相关联的值。为了简单起见, 我们把操作限于检查键是否存在。

基于同样的目的,我们同时将key的类型限制为int。因为int类型是编程语言中最常见、最容易被理解的数据类型。它也是最有可能在各种应用中被用作’id’的类型。

假设我们有一个使用整型id的应用,我们用它来识别客户的身份,我们还打算为它构建一个缓存。缓存是否被命中,决定了我们是否查找数据库。为该需求进行数据结构选择时,hashmap是几乎所有计算机科学学生的首选,它现在在C++中的实现被称为unordered_map。这是由于大O表示法(Big O notation)告诉我们查找哈希表所需要的时间是恒定的。还有哪些备选项?

1.  向量(vector),它的底层实现是一个数组,亦被称为连续的内存(contiguous memory)。

2.  树,它使我们可以进行分类遍历(sorted traversal),但是它也会导致更多的指针和可能的缺页异常(page fault)。

3.  链表(Linked list)。

实际上我们还可以有更多的选项,在这里我就不一一列举了。现在请大家思考一下,既然大O表示法告诉我们使用hashmap已经足够好了, 为什么我们还要考虑其他的选项呢?这是因为有时候大O表示法对我们的应用而言并不能起到很好的指导作用,这时使用小O表示法也许更恰当。我希望读者从中得到的启发是:测量所有东西(Measure Everything)。当需要在自己的机器上进行性能预测时,我们要养成测量的好习惯,因为它是你获得真正答案的唯一方式。 某些人可能会说,“使用向量!那样的话就可以对缓存线(cache lines)进行优化!”事实上,如果我们不把这些不同的方案放到一起进行测量,我们就不可能知道哪个更好。

时间: 2024-11-09 10:38:36

应用中如何使用适当的数据结构的相关文章

linux内核中与进程相关的数据结构(基于linux-mainline-rc4)

1.进程描述符    struct task_struct {  volatile long state; ....... struct list_head tasks; ....... struct mm_struct *mm, *active_mm; ....... struct vm_area_struct *vmacache[VMACACHE_SIZE]; ...... pid_t pid; pid_t tgid; .......   }所在文件:include/linux/sched.

NameNode中几个关键的数据结构

转载地址:http://blog.csdn.net/AE86_FC/article/details/5842020 NameNode启动过程详细剖析 NameNode中几个关键的数据结构 FSImage Namenode会将HDFS的文件和目录元数据存储在一个叫fsimage的二进制文件中,每次保存fsimage之后到下次保存之间的所有hdfs操作,将会记录在editlog文件中,当editlog达到一定的大小(bytes,由fs.checkpoint.size参数定义)或从上次保存过后一定时间

ES6中的Set、Map数据结构

Map.Set都是ES6新的数据结构,他们都是新的内置构造函数.也就是说typeof的结果,多了两个. 他们是什么:  Set是不能重复的数组.    Map是可以任何东西当做键的对象: ES6 提供了新的数据结构 Set.它类似于数组,但是Set成员的值都是唯一的,没有重复的值. let m = new Set(); m.add(1); m.add(2); m.add(3); m.add(3); m.add(3); m.add(4); m.add(5); console.log(m); 集合中

java 中的JDK封装的数据结构和算法解析(集合类)----链表 List 之 LinkedList

List 只要有两个实现类(ArrayList 和linkedList ),ArryList是基于数组实现,LinkedList是基于链表实现,下面是小弟对LinkedList的一点理解: LinkedList :基于链表实现的集合        双链接列表实现{ @code  List}和{ @code   Deque} 接口.实现了所有可选列表操作,和许可元素(including{ @code  null}). 首先对实现的接口分析一下: Deque  (双端队列): 这种队列允许在队列头和

java中的集合/容器的数据结构

最近双11在网上买了本 数据结构和算法--java语言实现,正在啃,同时在慕课网上的学习进度来到了集合框架这一类,对于这一块算是刚刚了解,本科的时候数据结构学习的是严蔚敏老师的那本数据结构,代码的实现貌似全部是伪代码,记得在期末考试的时候狠狠的通读了一遍,当时对于几个常见的数据结构队列.数组.栈.堆的一些方法还是比较熟悉,但是一直以来心里一直有个疑问,因为书上的都是伪代码,具体实现的方法并没有给出实例化,后来直到现在开始学习java语言,希望可以在之前理解的情况下,通过对于书籍上java代码的实

Android OpenCV中的几种基本数据结构

本文的代码基于OpenCV for Android 3.0 矩阵的类型结构 在opencv中,矩阵的类型结构被定义在opencv2/core/cvdef.h中,如下 #define CV_CN_MAX 512 #define CV_CN_SHIFT 3 #define CV_DEPTH_MAX (1 << CV_CN_SHIFT) #define CV_8U 0 #define CV_8S 1 #define CV_16U 2 #define CV_16S 3 #define CV_32S 4

PHP中使用数组实现堆栈数据结构的代码

在堆栈中,最后压入的数据(进栈),将会被最先弹出(出栈). 即在数据存储时采用"先进后出"的数据结构. PHP中,将数组当做一个栈,主要是使用array_push()和array_pop()两个系统函数来完成. 入栈主要是利用array_push()函数向第一个参数的数组尾部添加一个或多个元素,然后返回新数组的长度,示例如下: 复制代码 代码如下: <?php $zhan=array("WEB");//声明一个数组当做栈 array_push($zhan,&q

网络编程中重要的几个数据结构和函数

IPv4相关结构: struct in_addr { in_addr_t s_addr; //表示32位的IP地址,32位无符号整型 } struct sockaddr_in { uint8_t sin_len; //表示该结构体的长度,8位无符号整型 sa_family_t sin_family; //表示套接口使用的协议族,8位无符号整型 in_port_t sin_port; //表示套接口使用的端口号,16位无符号整型 struct in_addr sin_addr; //表示IP地址,

javascript中的Set和Map数据结构

Set数据结构 类似数组,所有的数据都是唯一的,没有重复值,它本身是一个构造函数 size 数据长度 add() 添加一个数据 delete() 删除一个数据 has() 查找一个数据 clear() 删除所有数据 //重复的数据会被删除 let set = new Set([1,1,2,3,4]); console.log(set) console.log(set.size)//4 //添加 console.log(set.add(5));//Set(5) {1, 2, 3, 4, 5} //