Performance Lua 5.1#运算符和字符串比较(性能)
为此:Performance Lua 5.1#运算符和字符串比较(性能),performance,lua,comparison,Performance,Lua,Comparison,为此: b = #{1,2,3} c = 'deadbeef' == 'deadbabe' b是用O(n)还是O(1)计算的?在什么情况下?行为是一致的,还是像稀疏数组行为一样依赖于上下文? 字符串比较是O(1)还是O(n)?我知道字符串是不可变的,Lua比较散列值,但是如果两个不同的字符串散列到同一个值呢? 请不要回答“儿子,不要担心低级行为”。我对低级行为感兴趣。多谢各位 编辑 3) #的结果是否存储在某个地方,还是每次我为同一数组调用它时都会进行计算?Lua字符串存储在一个表中,以避免创
b = #{1,2,3}
c = 'deadbeef' == 'deadbabe'
b是用O(n)还是O(1)计算的?在什么情况下?行为是一致的,还是像稀疏数组行为一样依赖于上下文?
字符串比较是O(1)还是O(n)?我知道字符串是不可变的,Lua比较散列值,但是如果两个不同的字符串散列到同一个值呢?
请不要回答“儿子,不要担心低级行为”。我对低级行为感兴趣。多谢各位
编辑
3) #的结果是否存储在某个地方,还是每次我为同一数组调用它时都会进行计算?Lua字符串存储在一个表中,以避免创建相同字符串的重复项,因此每次创建字符串时都需要对其进行散列,并在创建过程中与具有相同散列值的任何内容进行比较 创建后字符串对象的比较是O(1),因为Lua已经确保它们引用唯一的字符串,所以Lua只比较底层指针 当所有字符串都被内部化时,字符串相等性变为 指针相等
#定义等式(a,b)((a)==(b))
对于您介绍的表格案例:
通过实施:
表的长度在
O(logn)
中计算。算法大致如下:
- 通过采取步骤,尝试查找映射到
的整数索引。步长每次增加一倍。(如果在数组部分末尾发现nil
值,则可以跳过此部分。)nil
- 当找到此类索引时,在该索引和最后一个已知的非
索引之间的间隔上使用分治算法,以找到一个非nil
值,该值直接后跟一个nil
值nil
操作符的结果不会被缓存,因此每次在表上使用
时(不带\uu len
元方法),上述算法都会运行
关于字符串比较(用于相等):
较新的Lua版本内部有两种类型的字符串:短字符串(通常最多40字节)和长字符串。使用
memcmp
(如果长度匹配)比较长字符串,得到O(n)
。另一方面,短字符串是“interned”,这意味着当您在Lua中创建某个短字符串时,将检查是否已经存在具有相同内容的字符串。如果是这样,则重用旧字符串对象,而不分配新字符串。这意味着您可以简单地比较内存地址以检查短字符串是否相等,这就是O(1)
如果低级内容对您很重要,那么您可能应该使用一种可以控制低级内容的语言。您还可以查看,这些东西是如何实现的。但我的建议是:“儿子,不要担心低级行为”,如果你想用一种动态类型的、极其简单的脚本语言编写代码的话。在没有序列的表上使用默认值的结果值是未定义的(除非0适用)。在表中使用数组是一个实现细节。意外的结果很简单,{1,2,3,4,[6]=6}
的“长度”与5.2中的{1,2,3,[4]=4,[6]=6}
不同。3@rpattisoLua 5.2文件对此进行了澄清:“除非给出了一个_; len元方法,否则仅当表是序列时才定义表t的长度。”换句话说,不要这样做!
x = "deadbeef" -- put in string table
y = "deadbabe" -- put in string table
c = x == y -- compared pointers
t = {1, 2, 3} -- requires creating a table, hashing all the values etc.
b = #t -- constant time as array part is full and no hash part (ergo # is the array size)
t = [3] = nil
b = #t -- boundary inside array part, binary search in array, b=2
b = #t -- another binary search
t = {1, 2, 3, [1000]=4}
b = #t -- array is full, and 4 is not a key in the hash, b = 3