Lua源码阅读三——lua字符串缓存

lua源码阅读笔记与思路整理一 由于工作需要用了很多年的lua编写各种逻辑处理模块,今天心血来潮,决定深入了解一下lua源码的实现,目的是方便自己的lua代码调试,省的每次都用print打印这种原始手段,本“长篇小说“主要弄懂以下的问题: 1 local , global, upvalue 的原理和实现,upvalue的查找和递归标记是什么? 2 Function是什么,执行过程如何,参数如何传递,怎么分配栈上空间? 3... 阅读详情

本篇文章,主要探讨一下lua中的字符串缓存管理(涉及到的文件 lstring.c )。

 

在lua的9种数据类型中,字符串是属于可以被GC回收的类型。在lua中,操作字符串实际上是在操作字符串引用,当字符串不在被使用的时候,GC会通过一定算法回收。

 

--lua9种数据类型:

 

字符串分配

--源码:

 

 

ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString)));

--该行代码申请放置字符串的内存,luaM_malloc是申请内存的一个宏定义,调用上篇文章中提到的luaM_realloc_ 函数来来分配内存,在lua中字符串是用结构

 

表示的,所以申请的内存大小是(l+1)*sizeof(char)+sizeof(TString),内存分布:TString+str+'/0',然后给TString赋值hash code, len,marted,reserved,拷贝字符串。

  tb = &G(L)->strt;
  h = lmod(h, tb->size);
  ts->tsv.next = tb->hash[h];  /* chain new entry */
  tb->hash[h] = obj2gco(ts);
  tb->nuse++;

--接下来,将分配的字符串挂到全局字符串管理对象strt上

 

   if (tb->nuse > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)
    luaS_resize(L, tb->size*2);  /* too crowded */

--对字符串大小的扩充

 

字符串缓存

--源码:

 

 

 

  unsigned int h = cast(unsigned int, l);  /* seed */
  size_t step = (l>>5)+1;  /* if string is too long, don't hash all its chars */
  size_t l1;
  for (l1=l; l1>=step; l1-=step)  /* compute hash */
    h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1]));

---根据字符串长度l和字符串内容str计算字符串hash code,字符串hash code用作该字符串的key,后续用作字符串缓存key,这个算法可以保证key-value一一对应。

 

  for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)];
       o != NULL;
       o = o->gch.next) {
    TString *ts = rawgco2ts(o);
    if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) {
      /* string may be dead */
      if (isdead(G(L), o)) changewhite(o);
      return ts;
    }
  }

--在字符串全局管理对象中查找该字符串,如果查到就使用该字符串返回,否则:

return newlstr(L, str, l, h);

申请内存放置字符串。

 

 

 

Lua语法小贴士(四)字符串缓冲 我们在写Lua代码的时候,如果需要对一个字符串进行反复的连接操作的话,会造成极大的性能开销。因为字符串是不可变的值,所以当我们对字符串操作的时候,每次都会生成一个新的字符串。例如我们需要对一个10000字节的字符串str增加一个字符的时候,就会创建一个10001字节的字符串str_copy,然后再复制str到str_copy里面。所以我们需要字符串缓冲(string buffer)来解决这个问题,而Lua里面,string buffer就可以使用table来实现。 阅读详情

相关推荐

Redis 7.0 源码调试环境搭建与源码导读技巧

天下武功,无坚不摧,唯快不破!我的名字叫 Redis,全称是 Remote Dictionary Server。那么,作为开发工程师的你,是否愿意认真阅读此心法抓住机会来了解我,运用到你的系统中提升性能。我遵守 BSD 协议,由意大利人 Salvatore Sanfilippo 使用 C 语言编写的一个基于内存实现的键值型非关系(NoSQL)数据库。我是一个内存数据结构存储、可作为数据库、缓存、消息队列、流处理引擎,速度快是我的特点。根据官方数据,Redis 的 QPS 可以达到约 100000(每秒请求数

m0_71777195的博客 447

lua源码阅读

lua 源码阅读,个人阅读顺序,希望会对你有用

yajunjiao的专栏 1217

lua源码导读---云风

云风新作-----lua源码导读。目前网上最好的lua源代码阅读教程。帮助你快速理解lua实现原理。

LUA 源码阅读笔记(一)

好久没有在网上留言了。。。   背景介绍 因为工作的需要,后台svr要能够动态修改更新,使用C当然没有问题,问题就在于修改源码后,需要重启服务。所以就想到在C里能够嵌入一种脚本,最好是和C无缝结合的。因此就想到使用到LUALUA的大名圈内人士应该早有耳闻,只不过一直没有机会接触。机缘巧合,有幸一见。   俗话说得好,耳闻不如一见。LUA使用起来还是很简单的,语法和普通的脚本语言相差不大

zhucz333的专栏 839

lua学习笔记(2)让lua解释器支持中文变量和函数名 以及 重新让 解释器接受中文的关键字

今天再看lua 的解释器,突然想到我们的FAE 一直说要支持 脚本里面直接输入中文,于是我就去搜索了一下相关的实现流程,并且去简单的进行了一下操作。 代码位置 https://gitee.com/jeasonb/lua5.4.3_cn.git 0 获得 lua源码 wget http://www.lua.org/ftp/lua-5.4.3.tar.gz root@jeason:~/lua/lua_cn# wget http://www.lua.org/ftp/lua-5.4.3.tar.gz --20

jeason的博客 4693

Lua源码分析 - 数据结构篇 - 字符串池实现(05)

前面两章我们讲解了Lua的整个栈操作。本篇文章开始,我们重点阅读一下Lua的几个重要数据结构:字符串内存操作、对象操作等。 字符串操作对应的文件:lstring.c 字符串 - 数据结构 Lua字符串管理都会统一挂载到global_State全局状态机上。 字符串都会存储在TString对象结构上。Lua字符串管理分两种类型:链表方式存储(短字符串(<40)) 和 HashMa...

自娱自乐的代码人 3684

读书笔记《Lua设计与实现》 了解Lua底层

  孙广东  2017.10.8 http://blog.csdn.NET/u010019717   十一抽时间看了这本书。           还记得第一次接触Lua 是在2014年7月份, 当时还是在长春实习(Cocos Lua), 接触了一个多月就来北京开始了Unity   我是很喜欢看纸质书的,不太喜欢看电子书。 作者说这是第一本揭示Lua实现原理的图书。   这个历史就不...

游戏路上的小学生 1万+

Redis源码阅读【10-事务与Lua

Redis源码阅读【1-简单动态字符串】 Redis源码阅读【2-跳跃表】 Redis源码阅读【3-Redis编译与GDB调试】 Redis源码阅读【4-压缩列表】 Redis源码阅读【5-字典】 Redis源码阅读【6-整数集合】 Redis源码阅读【7-quicklist】 Redis源码阅读【8-命令处理生命周期-1】 Redis源码阅读【8-命令处理生命周期-2】 Redis源码阅读【8-命令处理生命周期-3】 Redis源码阅读【8-命令处理生命周期-4】 Redis源码阅读【番外篇-Redis的

Shinlyzsljay的博客 498

从零开始掌握Lua编程语言:5个步骤快速搭建开发环境

你是否想学习一门轻量级、高效且易于嵌入的编程语言?Lua编程语言正是这样一个理想选择。作为一门强大的脚本语言,Lua以其简洁的语法和高效的执行性能,在游戏开发、嵌入式系统和Web服务器中广泛应用。本文将带你从零开始,通过5个简单步骤快速搭建Lua开发环境,让你在30分钟内就能开始编写第一个Lua程序。 ## 📋 为什么选择Lua作为你的下一门编程语言? ### Lua语言的独特优势 Lua

gitblog_00671的博客 1047

KOReader终极跨平台电子书阅读器:从源码解析到多设备实战指南

KOReader是一款功能强大的开源电子书阅读器应用,支持PDF、DjVu、EPUB、FB2等多种格式,能够在Cervantes、Kindle、Kobo、PocketBook、reMarkable以及Android和Linux设备上流畅运行。这款专门为电子墨水屏优化的阅读软件,通过其出色的设备适配能力和丰富的功能特性,为技术爱好者和开发者提供了深入学习和定制开发的绝佳平台。 ## 🚀 深入KO

gitblog_01121的博客 510

Lua5.1代码阅读(六):ltm.h/ltm.c

一、概览 ltm.h/ltm.c的作用是提供查询元方法(元方法的值可能是函数,也可能是非函数的值)的API。 源码中把元方法称为标签方法(tag method)。 Lua的元方法有点像C++的运算符重载,用于覆盖一些Lua内部定义的默认行为。 参考链接: 1. LUA源码分析五:元表 http://lin-style.iteye.com/blog/1012138 2. Lua GC ...

Chinamming的专栏 296

Lua引擎框架设计与优化实践指南

Lua作为轻量级脚本语言,凭借其精简设计和高性能特性,在嵌入式系统和游戏开发中广泛应用。其核心原理基于虚拟机机制,通过Lua C API实现与宿主语言的高效交互,为系统提供灵活的脚本扩展能力。在性能优化方面,Lua表的预分配、局部变量使用和内存管理策略能显著提升执行效率。热更新机制和沙箱安全模型是Lua引擎框架的关键技术价值,支持游戏逻辑动态更新和嵌入式设备安全隔离。本文以LuaJIT和标准Lua对比为切入点,深入解析自研框架中的内存优化、定时器管理等实践方案,为高并发场景和资源受限环境提供解决方案。

weixin_30788239的博客 339

Lua 阅读源代码的次序

Lua 的源代码有着良好的设计,优美易读。其整体篇幅不大,仅两万行 代码左右。但一开始入手阅 读还是有些许难度的。 从易到难,理清作者编写代码的脉络非常重要。LuaJIT 的作者 在回答“哪一个开源代码项目 设计优美,值得阅读不容错过”这个问题时,推荐了一个阅读次序: 首先、阅读外围的库是如何实现功能扩展的,这样可以熟悉 LUA公开 API 。不必陷入功能细节。 然后、阅读 API 的具体实

TTc 's share 1620

Lua5.3源码阅读记录(3) ---- 字符串

存储一个字符串,从数据结构的角度来看 需要存储两个数据,一个是 字符串内存地址 ,一个是字符串的长度 ,首先我们需要明确的是Lua字符串是一个被内化的数据 ,这就意味着每个字符串类型的变量,实际存放的都是一个字符串的引用 ,例如 下面代码的a和b指向的是同一个字符串 ,换一种说话 ,假如执行 a = “Hello China” ,并不会将原本存储“Hello World”的内存修改为 “He...

Hui Ye的博客 783

lua 链表,集合,字符串缓冲

链表简单实现: 头结点变量:list 插入操作: list = {next = list,value = v} 集合的实现: 用集合的元素作为引用放入到table 基本结构: local reserved = { ["white"] = true, ["red"] = true, ["function"] = true, } if reserved["white"] then

2月7号遇见你 808

深入解析 Lua 源码内部:一个学习与探索的宝贵资源

深入解析 Lua 源码内部:一个学习与探索的宝贵资源 去发现同类优质开源项目:https://gitcode.com/ 在编程世界中,理解语言的底层机制是提升技能的关键步骤之一。对于 Lua 这种轻量级、高性能的脚本语言,其源代码库 提供了一个宝贵的平台,让开发者可以直接接触并研究 Lua 的核心实现。 项目简介 是 Lua 5.3 和 5.4 版本的源代码仓库,由lichuang维护。它不仅提...

gitblog_00063的博客 393

Lua源码分析 - 主流程篇 - 异常处理机制实现(09)

异常处理机制 -setjmp和longjmp 在讲解Lua的异常处理机制的时候,我们首先要看一下C语言的setjmp和longjmp的实现机制。 setjmp和longjmp分别承担非局部标号和goto作用。整体的逻辑如下: 使用setjmp,保存一个当前环境到jmp_buf跳转点,默认返回的值为0 程序继续执行,到某个地方调用longjmp,传入上面保存的jmp_buf,设置另外一个值...

自娱自乐的代码人 2832
上一篇: Lua源码阅读二——lua内存管理
下一篇: Lua源码阅读四——lua虚拟机指令系统
hong201
博客等级 码龄20年 49粉丝 136原创
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值