lua重新学习笔记2(table表)

CommonHeader:存放所有数据类型都通用的字段

lu_byte flags:这是一个byte类型的数据,用于表示这个表中提供了哪些元方法。最开始这个flags是空的,也就是0,当查找一次后,如果该表中存在某个元方法,那么将该元方法对应的flag bit置为1,这样下一次查找时只需要比较这个bit就行了。每个元方法对应的bit定义在ltm.h文件中。

lu_byte lsizenode:该表中以2为底的散列表大小的对数值。同时由此可知,散列表部位的大小一定是2的幂,即如果散列桶数组要扩展的话,也是以每次在原大小基础上乘以2的形式扩展。

struct Table *metatable:存放该表的原表。

TValue *array:指向数组部分的指针。

Node *node:指向该表的散列桶数组起始位置的指针。

Node *lastfree:指向该表散列桶数组的最后位置的指针。

GCObject *gclist:GC相关的链表

int sizearray:数组部分的大小。

table查找过程:

因为table包括散列表和数组两部分

if key为整数值,它的值>0且<=数组大小

      尝试在数组部分查看

else 尝试在散列表中查找

      计算出key的散列表,访问散列Node得到散列桶位置

      遍历散列桶下所有链表元素,直到找到key

 

resh过程:

1.分配一个位图nums,将其中所有位置设0,意义在于:nums数组中第i个元素存放的是key在2的(i-1)次幂和2的i次幂之间的元素数量。

2.遍历lua表中的数组部分,计算其中的元素数量,更新对应的nums数组中的元素数量。

3.遍历lua表中的散列桶部分,其中可能存放正整数。

4.此时nums数组已经有了当前这个Table中所有正整数的分配统计。逐个遍历nums数组,获得其范围区间内所有包含的整数数量大于50%的最大索引,作为重新散列之后的数组大小,超过部分的正整数,分配到散列桶部分。

5.根据上面计算得到的调整后的数组和散列桶大小调整表。

 

注意:

1.尽量不要将一个表混用数组和散列表部分。

2.尽量避免重新散列操作,代价重。

采用预填充技术会更好。当需要创建非常多的小表时,应预先填好表的大小,减少解释器被动地进行重新散列操作过程。

 

避免lua的rehash:(如何高效的用lua)

1)创建的时候先复制,初始化(避免rehash)

2)尽量多使用local

3)用table.concat()代替字符串concat是concatenate(连锁, 连接)的缩写. table.concat()函数列出参数中指定table的数组部分从start位置到end位置的所有元素, 元素间以指定的分隔符(sep)隔开。除了table外, 其他的参数都不是必须的, 分隔符的默认值是空字符, start的默认值是1, end的默认值是数组部分的总长。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值