探索Lua5.2内部实现:TString

以下内容转载自:http://blog.csdn.net/yuanlin2008/article/details/8423923

Lua使用TString结构体代表一个字符串对象。

lua532相应的结构体


hash用来记录字符串对应的哈希值,len用来记录字符串长度。

这个结构体其实只是字符串对象的头数据,后面紧跟着字符窜内容和一个'\0'结尾。字符串"abc"对应的TString对象应该如下图所示:

字符串对象的最终大小应该是TString的大小+字符串长度+1。

TString对应的lua对象类型为LUA_TSTRING。根据字符串长度(luaconf.h中的LUAI_MAXSHORTLEN,默认为40)的不同,TString对象还被分成两种子类型:LUA_TSHRSTR(短字符串)和LUA_TLNGSTR(长字符串)。

对于短字符串,在实际使用中一般用来作为索引或者需要进行字符串比较。不同于其他的对象,Lua并不是将其连接到全局的allgc对象链表上,而是将其放到全局状态global_State中的字符串表中进行管理。这个字符串表是一个stringtable类型的全局唯一的哈希表。当需要创建一个短字符串对象时,会首先在这个表中查找已有对象。所有的短字符串都是全局唯一的,不会存在两个相同的短字符串对象。如果需要比较两个短字符串是否相等,只需要看他们指向的是否是同一个TString对象就可以了,速度非常快。如果短字符串对象的extra > 0,表示这是一个系统保留的字符串。extra的值直接对应着词法分析时的一个token值,这样可以加速词法分析的速度。

对于长字符串,与短字符串相反,在实际使用中一般只是用来存储文本数据,很少需要比较或者索引。所以长字符串直接被挂接到allgc链表上当作普通的对象来处理。Lua不会对新创建的长字符串对象计算哈希值,也不保证长字符串对象的唯一性。当长字符串需要被用来当作索引时,会为其计算一次哈希值,并使用extra来记录是否已经为其计算了哈希值。

计算字符串的哈希值需要遍历字符串的每一个字符,如果字符串很长,会非常影响效率。对于大于等于32的字符串,Lua不会遍历每个字符,而是按照一定的间隔获取字符,最多遍历31次。这使得字符串的哈希值计算与字符串长度无关。

如果要将Lua部署到web上面来处理大量的基于文本的http请求,文本处理的安全性就变得尤为重要。为了防止Hash DoS攻击,字符串哈希值生成需要一个seed,这个seed是每次启动Lua时随机生成的。这就使不同的Lua实例对于同一个字符串会有不同的哈希值。
--------------------- 
作者:yuanlin2008 
来源:CSDN 
原文:https://blog.csdn.net/yuanlin2008/article/details/8423923 
版权声明:本文为博主原创文章,转载请附上博文链接!

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值