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