固定长度的数据结构很简单,大家每天都在用。
可变长度数据结构,都可以通过内嵌对象的形式,转化成固定长度的数据结构,大家每天也都在用,例如:
每个 person 对象的长度是固定的,但是,其内嵌的 name 和 address 是变长的。从而,整个对象占据的总空间也是变长的。
但是,将这样的的对象平坦化,使之只占据一块连续空间,使用的人很少,因为在绝大多数情况下,很少有人思考这个问题,并且,大多数问题已经使用内嵌数据结构解决掉了。
然而,如果内存很紧张,或者需要处理得数据量非常大,这种方式浪费的内存就太多了。假定我们现在创建了一个 map<int, person> ,在gcc4.1 的 64位环境中,按8字节对齐,这个 map 总共会占用多少内存呢?
- sizeof(map) = 48
- sizeof(string) = 8
- sizeof(person) = 24
- sizeof(person_node) = alignto(24 + 32(rbtree node overhead), 8) = 56
- sizeof(string_node) = 8*3(refcount, size_endptr, capacity_endptr)
- memsizeof(string) =sizeof(string_node) + alignto(strlen + 1, 8)
- memsizeof(person_node) = sizeof(person_node) + memsizeof(name) + memsizeof(address)
如果 avg(name) = 10, avg(address) = 20
实际占用的空间,大约还要再加上4:avg(name) = 14, avg(address) = 24
那么 memsizeof(person_node) = 56 + 24*2 +14 +24 = 142
那么该map 实际占用空间(gcc 的每个 map 还有一个虚结点:32个字节):
48+32+n*142 = 80+n*142
如果使用一种理想的变长数据结构,再加上红黑树的优化(none virtual node, compressed color, no parentptr),需要多少内存呢?
- sizeof(map) = 16
- memsizeof(person_node) = alignto(16(treenode) + 4(id) + 2*1(strlen) + 10(name) + 20(address) = 52, 8) = 56
memsizeof(map) = 16 + 56*n
内存一下节省了 60% 还多,也就是说,如果内存大小已经固定,可以装入 2.5 倍的数据。
- 如果用来做集群缓存,可以节省50%的机器(系统也要占一些内存)。
- 如果有5.6G的内存可用,就可以装入1亿条数据。
- 并且,在节省了60%内存的同时,还有另外一种好处:提高cache命中率,如果3个字段访问的频率相同,cpu的 cache miss 会降低3倍。
- 可以预见,因为cache miss降低,map.find 速度会大幅提高。
这个可变数据结构可以这样设计:
更复杂的情况:
- 如果nName 和 nAddress 要大于 255 呢?——把 unsigned char 改成 unsigned short, 甚至 unsigned int
- 如果person的字段很多,例如有20个字段:
这就不光是写代码的复杂了,运行时字段访问的性能也成问题!性能问题可以用另外一种方式——使用直接定位——来解决。
如果需要变长数据的数组,怎么办?简单,offset array + data byte array,具体实现方式与 person4 类似,只不过 offset array 元素需要使用更宽的整数。
分享到:
相关推荐
在TIA博途中,变长数组的声明通常以`Array[*] of 数据类型`的形式出现,其中`*`表示数组长度可变。 使用变长数组时,需要注意以下几点: 1. **接口参数定义**:当你在FC或FB的接口中使用变长数组时,应声明为`...
可变长度编码(Variable Length Coding, VLC)是数据压缩的一种常见方法,它根据数据的出现频率分配不同长度的编码,以达到更高的压缩率。然而,这种编码方式在某些应用场景下,如直接访问存储在内存中的压缩数据时...
Python 数据结构是编程中至关重要的概念,它们提供了一种组织和管理数据的方式,使得代码更加高效和易读。本文主要探讨了Python中的四个内置数据结构:集合(Set)、序列(Sequence)、映射(Mapping),以及它们的...
本文将深入探讨网络游戏如何利用可变长度封包(Variable Length Packet,VLP)和可变长度上行时隙(Variable Length Upstream Time Slot,VLUS)在单点对多点的无源光网络架构下实现高效的数据传输。 首先,无源光...
在"使用可变长度数据包的单点对多点无源光网络.pdf"这份资料中,可能详细介绍了PON系统的工作原理、可变长度数据包的封装与解封装机制、以及如何在实际网络游戏环境中优化数据传输。读者可以通过这份资料深入理解...
串是长度可变的字符序列,支持多种操作,如搜索、替换和插入。 数组是固定大小的、元素类型相同的线性集合,可以按索引访问。广义表是一种更通用的线性结构,可以包含其他列表作为元素。接下来,我们进入树和二叉树...
在电子行业中,可变长度编码(Variable Length Coding, VLC)是一种高效的数据压缩技术,广泛应用于数字信号处理、图像编码、音频编码以及数据通信等领域。它通过分配不同长度的编码来表示不同概率的输入符号,从而...
在编程领域,可变长数组(也称为动态数组)和字典树(又称Trie树或前缀树)是两种非常重要的数据结构。它们在不同的场景下有着广泛的应用,尤其在处理大量数据时能展现出高效的性能。 首先,我们来详细讨论可变长...
数据结构中的简易电子表格 数据结构课程设计中的简易电子表格是一种常见的设计题目,旨在让学生运用所学的数据结构课程知识,编写一个解决实际问题的大型或中等规模的计算机程序。下面我们将对该设计题目中的知识点...
串是长度可变的一维数组,支持各种字符串操作。树和二叉树是复杂的非线性数据结构,广泛应用于文件系统、编译器设计和图形表示。二叉树的遍历、性质和存储方法,以及Huffman树和编码是重要的学习内容。图数据结构...
可变长顺序表是一种数据结构,能够方便地选择是插入还是删除,界面以菜单的形式,方便易懂。下面是对可变长顺序表的详细介绍: 可变长顺序表的定义 可变长顺序表是一种特殊的顺序表,其长度可以动态变化。它可以在...
串是长度可变的一维数据结构,由字符序列组成。串的操作包括连接、子串查找、模式匹配等。本章将深入讲解串的各种操作及其在文本处理中的应用。 **第5章 数组和稀疏矩阵** 数组是一种固定大小、按顺序存储的数据...
可变长度编码是一种数据压缩技术,它根据符号出现的概率分配不同长度的编码。常见的VLC有霍夫曼编码(Huffman Coding)和算术编码。这种编码方式能有效利用比特流,对频繁出现的符号赋予较短的编码,不常出现的符号...
Java中的数组是静态分配内存的,长度不可变。 - **链表**:节点包含数据和指向下一个节点的引用,适合频繁插入和删除操作。 - **栈**:后进先出(LIFO)结构,主要用于函数调用、表达式求值等场景。 - **队列**:...
- 字符串的存储:定长数组、动态数组(可变长度串)和链表。 5. **第5章 递归** - 递归定义:函数调用自身,用于解决分治和回溯问题。 - 递归的基本要素:递归函数、递归结束条件和递归步骤。 - 递归应用:快速...
标题中的“电子-一种玻璃封装螺纹旋进可变长度热电偶”指的是在电子行业中应用的一种特殊类型的热电偶,其设计特点是采用玻璃封装,具有螺纹旋进结构,并且能够根据需求调整其感测长度。热电偶是测量温度的传感器,...
4. **第四章 串**:串是字符序列,类似于数组,但其长度可变。本章讲解了串的模式匹配、子串查找等操作,以及串的各种存储方式。 5. **第五章 数组和广义表**:数组是最简单的数据结构,提供了随机访问的能力。广义...
在准备考研特别是目标为西安交通大学的软件工程专业的学生,数据结构是不可或缺的一门专业课程。西安交大的数据结构考研真题资料,提供了重要的历年试题及解答,有助于考生更好地理解和掌握数据结构的知识点,为考研...
串是长度可变的一维数组,主要用于处理文本数据。这一章将介绍串的基本操作,如串的连接、子串查找、模式匹配等,以及串的各种存储方式,如定长串、可变长串和稀疏串。 第五章 数组 数组是相同类型元素的有序集合,...