lua 源码阅读(二)

2017-12-16 09:41编辑本页

lua 源码系列文章:

读完风云关于 lua 的字符串部分,对 lua 的字符串处理也有相应的理解。

Contents

String

lua 的字符串在 lua 内部分为长字符串和短字符串,而这两种特性在 lua 层面是透明的,这种分类应该只是lua 解释器内部的优化。

补充1: 其中短字符串的最大长度由 LUAI_MAXSHORTLEN 宏决定。长字符串调用 createstrobj 来创建。

长短字符串主要在字符串创建、比较时做不同的处理。

字符串创建时,短字符串直接进行内部化,并且在 TString 结构体中的 extra 位上标记是否为内部保留字段。而长字符串在创建时,是直接进行内存拷贝,在 extra 位上进行标记,以在比较或者内部化时进行惰性哈希。

字符串比较时,短字符串直接对比指针地址。而长字符串则进行逐字符串比较。

补充2: 长/短字符串的优化是从 Lua 5.2.1 开始加入的,在那之前所有的字符串都是保存在全局的哈希表中。

补充3: 在字符串拼接时,使用 .. 是低效的,这其中涉及申请内存以及内存拷贝。建议使用 table.concat4 或者 string.format5

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

参考文章:


Lua中字符串类型的源码实现


  1. 2018-11-01 补充 ↩︎

  2. 2018-11-01 补充 ↩︎

  3. 2018-11-01 补充 ↩︎

  4. table.concat 底层拼接字符串的方式也是使用运算符.. ,但是其使用算法减少了使用运算符..的次数,减少了GC,从而提高效率。主要思路:采用二分思想,用栈存储字符串,新入栈的字符串与下方的字符串比较长度,大于则使用运算符..拼接成新字符串,并移除栈顶的字符串,不断向下直至遇到长度更大的字符串或者栈底,这样保持最大的字符串位于栈底,栈呈现金字塔的形状,最终在使用运算符..将栈中的字符串拼接成最终的字符串。 作者:AaronChanFighting 来源:CSDN 原文:https://blog.csdn.net/qq_26958473/article/details/79392222 ↩︎

  5. string.format 的每个 %s 占位符,有 512 个字符的限制 ↩︎

除另有声明外 本博客文章均采用 知识共享(Creative Commons) 署名 4.0 国际许可协议 进行许可 转载请注明原作者与文章出处


标签: lua

点击加载Disqus评论
Creative Commons © 2013 — 2023 xiaocang | Theme based on fzheng.me & NexT | Hosted by Netlify