lua 源码系列文章:
读完风云关于 lua 的字符串部分,对 lua 的字符串处理也有相应的理解。
Contents
String
lua 的字符串在 lua 内部分为长字符串和短字符串,而这两种特性在 lua 层面是透明的,这种分类应该只是lua 解释器内部的优化。
补充1: 其中短字符串的最大长度由 LUAI_MAXSHORTLEN
宏决定。长字符串调用 createstrobj
来创建。
长短字符串主要在字符串创建、比较时做不同的处理。
字符串创建时,短字符串直接进行内部化,并且在 TString
结构体中的 extra
位上标记是否为内部保留字段。而长字符串在创建时,是直接进行内存拷贝,在 extra
位上进行标记,以在比较或者内部化时进行惰性哈希。
字符串比较时,短字符串直接对比指针地址。而长字符串则进行逐字符串比较。
补充2: 长/短字符串的优化是从 Lua 5.2.1 开始加入的,在那之前所有的字符串都是保存在全局的哈希表中。
补充3: 在字符串拼接时,使用 ..
是低效的,这其中涉及申请内存以及内存拷贝。建议使用 table.concat
4 或者 string.format
5
userdata
在 lua 中还存在一种 UData
的结构,这叫做 userdata,这种数据结构主要是在 lua 在与 c 和 c++ 交互时,将 c 的数据结构交给 lua 的 gc 处理。
具体来讲,在C中可以使用 lua_newuserdata()
会在 lua 中创建一个数据结构,并将指针返回。这和 malloc
的调用差不多,但区别是你不用手动调用 free
来释放内存,而交给 lua 的 gc 即可。
一个好的例子是 lua 的 io
库,其中将 FILE *
的 C 数据结构放入 lua 的 userdata 中,通过实现一个 __gc
的元方法,可以实现将文件句柄在 gc 时自动关闭。
https://github.com/xiaocang/lua-5.2.2_with_comments/releases/tag/lua_string_02
参考文章:
2018-11-01 补充 ↩︎
2018-11-01 补充 ↩︎
2018-11-01 补充 ↩︎
table.concat
底层拼接字符串的方式也是使用运算符.. ,但是其使用算法减少了使用运算符..的次数,减少了GC,从而提高效率。主要思路:采用二分思想,用栈存储字符串,新入栈的字符串与下方的字符串比较长度,大于则使用运算符..拼接成新字符串,并移除栈顶的字符串,不断向下直至遇到长度更大的字符串或者栈底,这样保持最大的字符串位于栈底,栈呈现金字塔的形状,最终在使用运算符..将栈中的字符串拼接成最终的字符串。 作者:AaronChanFighting 来源:CSDN 原文:https://blog.csdn.net/qq_26958473/article/details/79392222 ↩︎string.format
的每个%s
占位符,有 512 个字符的限制 ↩︎