小夕在本系列前两篇文章中为大家介绍了各类数据结构的扩容策略,且在上篇文末,小夕提到了加倍式扩容中,倍率采用2并不是最优的,为什么呢?有没有最优倍率呢?

内存复用

如果倍率采用2甚至更大的数,那么被开辟过的旧空间永远都不会被新开辟的空间利用。小夕举个栗子。

if(倍率≥2){

那么以下是小夕为大家画的三次扩容后的内存块的占用情况(小夕用PPT画的,好麻烦的喵,读者喵有好用的轻量级画矢量图的软件记得推荐给小夕哦~)

上图中,内存块一共有15个字节。粉色实心框是数据结构占用的内存块,空心框是空闲的内存。

假如一开始数据结构的大小是1字节,占用了0xFF00这个字节,如图中第一列。然后第一次扩容后数据结构大小变成2字节,无法利用之前的旧内存空间。

同样,第二次扩容,第三次扩容后,数据结构的大小总是要比之前累计占用的旧内存空间之和还要大,总是大1个字节,所以永远都无法重新利用之前的旧内存空间。

那么无法复用旧内存空间,对应有程序与操作系统各有什么影响呢?小夕还没有探索出严谨的结论,读者有思路可以跟小夕一起讨论哦~

如果倍率改为比2大的数,结果是一样的。有兴趣的喵喵可以自行画画图~当然,数学好的喵喵不用画图也能证明出来的~(利用几何级数的性质)

}

if(倍率<2&&倍率>1){

比如倍率采用1.5。小夕再画一下图~

可以看到,第三次扩容后的新数据结构大小约为338B!而旧空间的大小是250+225=475>338,也就是说新的哈希表可以挪到旧的内存空间了!内存得到了复用!

好咯,说到这里,读者应该懂了,对于加倍式扩容,倍率必须小于2才能复用内存。那么为什么默认值取1.5,而不是1.6,1.7呢?小夕查了很多资料,发现这是一个启发式策略(启发式策略就是拍脑袋想出来的看似合理而没有严谨理论依据的方法)。

一个疑问

那么既然看似倍率用1.5要优于2,为什么Java中的哈希表系列以及C++中的Vector却采用2呢?

这就是理论与工程的不同之处。在工程中不仅要考虑内存复用这一个问题,还要考虑到浮点数运算问题和大量数据场景下的扩容速度的问题

具体来说,若采用1.5倍,那么假设数据结构初始大小为10,则以后的数据结构大小会依次计算为:

15,

22.5,

33.75,

50.625,

75.9375

...

可以看到浮点运算的代价会越来越高。

扩容速度也很好理解。大量数据时,2倍扩容速度会比1.5倍扩容速度少很多次扩容次数,因此效率会比1.5倍高很多。那么当程序不怎么看重内存复用,却有大量数据待填入数据结构时,2倍是更合理的。

So

虽然很多数据结构都是基于静态数组实现的动态空间增长,但是有的是上述提到的2倍的扩容倍率,有的像Java中的ArrayList则为1.5倍的扩容倍率。

看来如何决定倍率,要在设计数据结构的时候好好考虑这个数据结构将来的业务场景呢。

PS:

没有发现小夕在上面的一个if语句中漏了一半括号的C/C++/Java等程序员请自觉面壁思过。

最后,不知道您对小夕的文章是否满意呢(⁎⁍̴̛ᴗ⁍̴̛⁎)

小夕已委托维权骑士对小夕发布文章的版权行为进行追究与维权。欢迎大家转发分享~如需转载,请联系微信xiyaomengmengda。‍

小夕说,不了解动态空间增长的程序喵都是假喵(下)相关推荐

  1. 【萌味】小夕说,不了解动态空间增长的程序喵都是假喵(中)

    亲爱的小屋客人,昨天小夕将小屋的讨论室重新装修啦!希望您会喜欢哦~除了口令[d],现在也可以通过主页下方的"喵了个咪"进入讨论室啦. ps:昨天小夕装修讨论室的时候发生了N次差点吐 ...

  2. 【萌味】小夕说,不了解动态空间增长的程序喵都是假喵(上)

    小提示:小夕会将小屋的最新动态更新到小屋的布告栏哦,口令是[nb](口令在订阅号主界面直接回复即可使用). 小夕学了数据结构后,知道了链表.树.哈希表等数据结构与静态数组的固定容量不同,它们是可以动态 ...

  3. 【错误修正】关于文章《小夕说,不了解动态空间增长的程序喵都是假喵》

    感谢某位粉丝的来信,小夕在该系列文章中有如下错误,请已经读过该系列文章的同学务必留意一下. 1.C++中的向量的写法是vector,而不是Vector!首字母不要大写! 2.在<小夕说,xxxx ...

  4. sql server 监视_如何在SQL Server中监视对象空间增长

    sql server 监视 介绍 (Introduction) There are many situations in a DBA's life that lead him or her to mo ...

  5. 【小夕精选】如何优雅而时髦的解决不均衡分类问题

    之前小夕因项目需要研究了一小阵子的不均衡(文本)分类问题,不过没有研究的太过深入,也没有总结出一套成体系的处理思路.正好今天发现数据挖掘大佬「微调」在知乎上写了一个言简意赅又很具有实际操作价值的回答, ...

  6. 【小夕精选】多轮对话之对话管理(Dialog Management)

    这一篇是一段时间之前小夕初入对话领域时刷到的徐阿衡小姐姐写的一篇文章,写的深入浅出,十分适合有一定基础的情况下想快速了解对话管理技术的童鞋阅读~另外顺手推一下阿衡小姐姐的订阅号「徐阿衡」,干货满满不要 ...

  7. 文本分类问题不需要ResNet?小夕解析DPCNN设计原理(下)

    哎呀呀,说好的不拖稿的又拖了两天T_T,小夕过一阵子分享给你们这两天的开心事哦.后台催稿调参系列的小伙伴们不要急,下一篇就是第二篇调参文啦. 好啦,接着上一篇文章,直接搬来DPCNN.ShallowC ...

  8. 文本分类问题不需要ResNet?小夕解析DPCNN设计原理(上)

    历史回顾 回顾一下图像和文本的发展史,似乎这就是一场你追我赶的游戏.在上一阶段的斗争中,朴素贝叶斯.最大熵.条件随机场这些理论完备的统计机器学习模型使得文本分类.中文分词.NER等诸多自然语言处理问题 ...

  9. 中国5G毫米波小基站市场行业运行动态与发展趋势预测报告

    中国5G毫米波小基站市场行业运行动态与发展趋势预测报告2022-2028年 详情内容请咨询鸿晟信合研究院! [全新修订]:2022年3月 [撰写单位]:鸿晟信合研究网 2021年中国5G毫米波小基站市 ...

最新文章

  1. 问题:为命名空间,在此被用作类型和此项目作为引用添加将导致循环依赖项
  2. Linux下mknod的作用,Linux系统mknod命令用法
  3. bat set命令详解
  4. 一行代码取出HTML页面某个按钮的css属性,比如margin
  5. IP3 三阶交调截取点测试(转帖)
  6. grub4dos中的不容易理解的问题
  7. 将旧版本从Java EE 5减少到7
  8. 静态html的ajax如何发请求,静态页面ajax - 冥焱的个人空间 - OSCHINA - 中文开源技术交流社区...
  9. android新建项目错误,新建Android项目出错
  10. linux基础--awk文本分析工具详解
  11. 计算几何——poj1410,线段不规范交
  12. flash将文本呈现为html,flash中的静态文本、动态文本、输入文本
  13. python基础学习之python操作PDF文件、发送邮件添加附件10
  14. 深度解析Contains底层代码
  15. Using setJavaScriptEnabled can Introduce XSS Vulnerabilities into
  16. 简单并不粗暴:自学产品的8个方法
  17. 英语长语法难句——状语和状语从句
  18. YOLOv5改进之十七:CNN+Transformer——融合Bottleneck Transformers
  19. 健身场馆应用软件提供商
  20. 我的世界服务器start文本文档怎么输,我的世界1.12怎么用各种指令打出彩色字~ 经验告诉你该这样...

热门文章

  1. 花了一年时间开发出来的基于DXF文件的加工路径自动生成软件
  2. #define va_arg(AP, TYPE)
  3. Android系统充电系统介绍-预防手机充电爆炸
  4. Linux 进程管理数据结构
  5. 嵌入式软件面试(基础题)总结,不断更新
  6. 串口UART串行总线协议
  7. python2编码问题解决了吗_Python2编码问题
  8. VS2019调试查看变量_你很可能需要知道这个调试小技巧
  9. python题库刷题训练软件_Python基础练习100题 ( 11~ 20)
  10. mac最好用的markdown_「建议收藏」PCMaclinux,最好用Markdown编辑器清单