Lua 5.1 # 运算符和字符串比较(性能)
2014-11-12 14:49:16
收藏:0
阅读:286
评论:2
这是什么:
b = #{1,2,3}
c = 'deadbeef' == 'deadbabe'
在什么情况下b是O(n)或O(1)计算的?这种行为是一致的,还是像稀疏数组行为一样依赖上下文? 字符串比较是O(1)还是O(n)?我知道字符串是不可变的,Lua比较哈希值,但如果两个不同的字符串哈希到相同的值怎么办? 请不要回答“别担心低级行为,孩子”。我对低级行为很感兴趣。谢谢。
编辑
3)#运算符的结果是否储存在某处,还是每次我对相同的数组调用时都会计算?
点赞
用户3677376
表的长度在 O(log n) 中进行计算。算法大致如下:
- 尝试通过取一步来找到一些整数索引映射到
nil。 步幅每次翻倍。 (如果在数组部分末尾找到了一个nil值,则可以跳过此部分。) - 当找到这样的索引时,在此索引和最后一个已知非
nil索引之间使用分治算法来查找一个直接跟随nil值的非nil值交替的区间。
在此处查看详细信息 here。如果您具有连续的值序列,则此算法运作良好,但如果数组之间有空洞,则可能产生意外的结果。
编辑:内置的 # 运算符的结果不会被缓存,因此每次在表上使用 #(没有 __len 元方法)时,上述算法都会运行。
关于字符串比较(相等性):
较新的 Lua 版本在内部有两种字符串类型:短字符串(通常最多达到 40 字节)和长字符串。 如果长度匹配,长字符串使用 memcmp 进行比较,因此您可以得到 O(n)。 另一方面,短字符串则被“interned”,这意味着当你在 Lua 中创建某个短字符串时,会检查是否已存在具有相同内容的字符串。 如果有,则重用旧字符串对象,并且不会分配新字符串。 这意味着您可以比较内存地址以检查短字符串的相等性,这是 O(1)。
2014-11-12 13:44:58
评论区的留言会收到邮件通知哦~
推荐文章
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
Lua字符串存储在表中,以避免创建相同字符串的副本,因此每次创建字符串时,需要将其哈希并与具有相同哈希值的任何内容进行比较来创建它。
在创建后比较字符串对象的比较是 O(1),因为Lua已确保它们引用唯一的字符串,因此Lua只需比较基础指针。
x = "deadbeef" -- 放入字符串表中 y = "deadbabe" -- 放入字符串表中 c = x == y -- 比较指针对于您提供的表格情况:
来自 ltabl.c:int luaH_getn (Table *t) 的实现:
t = {1, 2, 3} -- 需要创建一个表,哈希所有值等。 b = #t -- 数组部分已满且没有哈希部分(因此#是数组大小),因此是常数时间。 t = [3] = nil b = #t -- 在数组部分内找到边界,二分搜索数组,b = 2。 b = #t -- 另一次二分搜索 t = {1, 2, 3, [1000]=4} b = #t -- 数组已满,4不是哈希中的键,b = 3。