Lua性能优化之table_lua table宽容 2幂-程序员宅基地

技术标签: Lua性能优化  Lua  

通常情况下,我们不需要知道Lua的table是如何实现的,但是为了对lua性能进行优化,去了解Lua table的实现细节是非常关键的。

01

table是如何实现的?

为了了解table的实现,我们可以查看Lua的C源码,如下:

 

图1-1 lua表的构成

Lua中的table是由两部分组成,数组部分和哈希表部分。数组部分储存着索引为整型的数据,哈希表存储着以其它类型为索引的键值对。哈希表使用一个哈希算法来计算键值对的key值,采用开链法来处理哈希冲突。当我们声明一个表t = { },此时t的数组部分和哈希表部分的大小都是0,当不断向数组插入键值对的时候 如下:

  • a[1] = 1 ,大小不够,需要扩容,扩容后数组部分的大小为1

  • a[2] = 2 ,大小不够,需要扩容,扩容后数组部分的大小为2

  • a[3] = 3 ,大小不够,需要扩容,扩容后数组大小为4.

执行扩容的过程叫做rehash,每次rehash时,会遍历整个table的数组部分和哈希表部分,统计其中有效的键值对,大小不够,则会扩容,扩容后的大小为2的整数幂次方,且保证rehash操作后整个数组部分的使用率大于50%。每次rehash都很耗时,使用table,我们应该尽量减少rehash。

  

02

如何减少Rehash?

    1.不要使用多个size较小的table,如果可以使用大的table来代替。

    由第一部分可以看到,当table的size从0扩展到4的时候需要3次rehash。因此当table尺寸较小时,向table中插入元素,很容易触发rehash,因此不要过多的使用小table,使用一个大的table来整合小的table。

     2.初始化table的写法。

    对于第一部分的t={},我们可以声明t的时候就对t进行初始化 即:

            t={1,2,3},

    这样会直接产生一个size=3 的表t,也就没有了3次rehash。需要注意的是:

            t ={[1]=1,[2]=2,[3]=3},

    这种写法t的数组部分的大小也为4,会执行三次rehash。

       3.将table置空的注意点

table size大小的变化只会在触发rehash的时候进行,因此当我们将table中的某个键值对的值设置为nil的时候,Lua并不会执行减小size的操作。当执行rehash的时候,Lua才会查找所有为nil的元素,并且决定是否reduce size。例如

        local t = {} 

        for i =1,100000 do

    t[i] = i

end

print(collectgarbage("count"))

--置为nil

for i =1,100000 do 

    t[i]=nil

end

print(collectgarbage("count"))

上面两次结果相同,但是当我们

for i= 100001,200000 do

    t[i] = nil

end

print(collectgarbage("count"))

此时结果会变小,因为当遍历到20000时,发现数组大小不够,触发rehash,rehash会保证数组部分的使用率大于50%,因此会减小数组部分的大小。为nil的也会被删除。

又比如当我们直接声明一个local t ={}  t[100] =1,此时为了保证数组的使用效率大于50%,会直接将键值对{100,1}储存在hash表部分。

 4. 常见的清空table的写法。

    方法一:

             for k in pairs(t) do  t[k] =nil end

    方法二

        while true do

            local k  =next(t,nil)

                if not k then

                    break

                end

             t[k] = nil

        end

第二种写法比第一种写法要耗时。next每次返回当前key的值和下一个不为nil的元素的key。当传入的key为nil的时候,每次返回第一个部位nil的键值对的值。第二种写法每次传入的key都为nil,随着table被不断置为nil,寻找第一个不为nil的键值对,将会越来越耗时。而pair虽然也是用next实现的,但是配合上泛型迭代器for,每个循环都会获得上个循环的状态,因此效率上要快很多。第一种写法等价于:

for k,v in next(t,nil) do,每个循环都将next返回的key传入下一个循环的next。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/kangluo1/article/details/104238041

智能推荐

程序员必备书单 | 10本经典好书推荐,提升编码技能_编码书本推荐-程序员宅基地

文章浏览阅读358次。程序员必备书单 | 10本经典好书推荐,提升编码技能_编码书本推荐

OCTAVE_octave由来-程序员宅基地

文章浏览阅读827次。OCTAVE介绍: Octave是一种高层解释类编程语言,旨在解决线性和非线性的数值计算问题。Octave为GNU项目下的开源软件,早期版本为命令行交互方式,4.0.0版本发布基于QT编写的GUI交互界面。Octave语法与Matlab语法非常接近,可以很容易的将matlab程序移植到Octave。同时与C++,QT等接口较Matlab更加方便。 它最初是一个用于本科生化工反应器设计的教学课件,_octave由来

机器学习、深度学习需要哪些数学知识?_机器学习用哪种数学只是更多?-程序员宅基地

文章浏览阅读1.1k次,点赞4次,收藏16次。如果不是有太多自由时间,不要过度投入到数学上,或者说不要系统大量地学习,可以遇到不懂的再去学习相关数学知识。(本文部分摘自图灵的猫公众号 )微积分微积分是现代数学的基础,线性代数,矩阵论,概率论,信息论,最优化方法等数学课程都需要用到微积分的知识。单就机器学习和深度学习来说,更多用到的是微分。积分基本上只在概率论中被使用,概率密度函数,分布函数等概念和计算都要借助于积分来定义或计算。 几乎所有学习算法在训练或者预测时都是求解最优化问题,因此需要依赖于微积分来求解函数的极值,而模型中某些函数的选取_机器学习用哪种数学只是更多?

JavaScript 中的函数式编程实践-程序员宅基地

文章浏览阅读58次。http://www.ibm.com/developerworks/cn/web/1006_qiujt_jsfunctional/ JavaScript 是一门优美的语言,具有动态性,弱类型,并有 C 和 LISP 的双重语法,重要的是,她本身是“可编程”的。文章先对 JavaScript 的函数式编程特性做一些介绍,然后讨论函数式编程在实际项目中..._javascript node 18.12.2 实现一个sum函数,输入位为一个数组,输出为数组内

解决c++string类型变量无法输出中文的问题(环境:mingw+vscode)_c++string不能输出中文-程序员宅基地

文章浏览阅读933次。我也是在网上找了好久解决办法 其实很简单在visual code终端中输入chcp 936即可。_c++string不能输出中文

3D点云目标检测Complex-YOLO(训练篇)(一)———KITTI数据集预处理与制作_complex-yolo训练自己的数据集-程序员宅基地

文章浏览阅读5.8k次,点赞10次,收藏101次。KITTI datasetDownload datasetKITTI 3D Object Detection Evaluation 2017 link下载四个部分,共41.4GB解压后为四部分内容(相机校准矩阵calib、RGB图像image_2、标签label_2、点云数据velodyne) 对应的testing和training数据。其中,training数据为7481张(图片和点云对应的场景),testing数据 7518张(无label_2数据)。Data Preprocess_complex-yolo训练自己的数据集

随便推点

了解微信小程序_下列那些程序应用不可以使用java进行开发()?aharmonyos 应用bandroid应用c微信-程序员宅基地

文章浏览阅读333次。了解微信小程序微信小程序官方网址:https://mp.weixin.qq.com/cgi-bin/wx某大神知乎专栏地址:七月在夏天https://zhuanlan.zhihu.com/oldtimes小程序的特点  小程序适合做简单的,用完即走的应用。  小程序适合低频的应用。  小程序适合性能要求不高的应用。那些类型的应用适合小程序  微信之父张小..._下列那些程序应用不可以使用java进行开发()?aharmonyos 应用bandroid应用c微信小程序djava web应用

内修昇思MindSpore AI框架,外重行业汇聚,华为大模型的不平凡之路_使用华为的的卡训练模型必须是mindspore吗-程序员宅基地

文章浏览阅读440次。要说近几年深度学习领域最热门的研究课题有哪些?大模型肯定在列。从 2020 年 OpenAI 发布 1750 亿参数的 GPT-3 开始,炼大模型这股潮流变得不可阻挡。依托自身效果好、泛化能力强等特点,大模型进一步增强 AI 的通用性,更成为 AI 技术和应用的新基座。科技巨头们纷纷下场,接连推出千亿甚至万亿参数级的大模型。而纵观现有大模型,NLP、CV 以及多模态成为三个主要的发力方向,这些偏向于基础大模型;同时,能否落地应用成为检测大模型能力的重要指标,因此具备丰富领域知识的行业大模型也越来越受到业界的_使用华为的的卡训练模型必须是mindspore吗

Flutter中TabBarView与PageView该如何选择_flutter tabbarview pageview-程序员宅基地

文章浏览阅读1.6k次。TabBarView和PageView都可以用来当作导航切换的容器。但还是有一些使用的区别。区别TabBarView主要展示不同ui的容器,配合TabBar导航,点击tab时,切换到不同的ui界面。比如微信,有微信、通讯录、发现、我 4大不同的模块。PageVieiw主要是展示相同页面的容器,比如今日头条app首页,根本不同的新闻类型展示不同的新闻,但页面的布局是一样的。另外PageView还支持左右滑动,可以和TabBar做联动。..._flutter tabbarview pageview

当element表单验证根据别的值动态校验的解决办法_element ui 表单其中一个校验是以另一个值来判断-程序员宅基地

文章浏览阅读1.3k次。公司项目,打个马赛克,见谅!表单是否影响日期的必填校验。为是时,日期必填,为否时,日期可不填。具体方法为根据是否的值来改变required的值。_element ui 表单其中一个校验是以另一个值来判断

【学习摘记】马士兵bbs改良版_课时22-24_FCKEditor-程序员宅基地

文章浏览阅读373次。【课时22】FCKEditor_1——开阔眼界:还有这么一个东西,我们可以用,而且很简单我们就把它用起来了我现在讲的这个reply呢,其实和上一个老的bbs讲的reply其实没什么区别。你如果想看呢,可以看老的,也可以看现在写的这个。但是我如果老讲同样的东西,你不烦我都觉着烦了。老师像是这么因循守旧、不思进取的人么?所以教一点新鲜玩意——不是很重要,但是教着玩~将来,有朝一日,

【案例练习】18—27个适合初学前端开发人员的项目练习案例-程序员宅基地

文章浏览阅读2k次,点赞4次,收藏38次。编辑整理 | 杨小爱今天我们将深入学习一些网站页面的项目练习,通过案例的练习,以提高我们的编程开发设计能力,今天的案例练习主要涉及到的知识有HTML、CSS、Javascript,通过练习,你也可以将这些知识应用到实际的网站开发中!01、响应式社交平台演示地址:https://codepen.io/TurkAysenur/pen/RwWKYMO02、福克斯新闻页面演示地址..._前端练习图片