是否Lua的优化" .."运营商? [英] Does Lua optimize the ".." operator?

查看:191
本文介绍了是否Lua的优化" .."运营商?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须执行以下code:

I have to execute the following code:

local filename = dir .. "/" .. base

数千次在一个循环(它是打印目录树递归)。

thousands of times in a loop (it's a recursion that prints a directory tree).

现在,我不知道Lua中是否地连接了3串(DIR,/,基地)一次性(即,通过分配足够长的时间来保存他们的总长度的字符串),或者是否做这是否低效方式它在内部在两个步骤:

Now, I wonder whether Lua concatenates the 3 strings (dir, "/", base) in one go (i.e., by allocating a string long enough to hold their total lengths) or whether it does this the inefficient way by doing it internally in two steps:

local filename = (dir .. "/")              -- step1
                               .. base     -- step2

由于两个字符串分配的只有一个,而不是最后的方式是低效的内存明智的。

This last way would be inefficient memory-wise because two strings are allocated instead of just one.

我不那么在意CPU周期:我关心的主要是内存消耗

I don't care much about CPU cycles: I care mainly about memory consumption.

最后,让我概括的问题:

Finally, let me generalize the question:

当它执行以下code Lua中是否只分配一根弦,或4?

Does Lua allocate only one string, or 4, when it executes the following code?

local result = str1 .. str2 .. str3 .. str4 .. str5

顺便说一句,我知道我可以这样做:

BTW, I know that I could do:

local filename = string.format("%s/%s", dir, base)

但我还没有基准它(存储兼; CPU明智的)。

But I've yet to benchmark it (memory & CPU wise).

(顺便说一句,我知道表:。CONCAT()这有创建表,所以我想它不会在所有的用例有利于增加开销)

(BTW, I know about table:concat(). This has the added overhead of creating a table so I guess it won't be beneficial in all use cases.)

奖金问题:

在Lua的情况下,不优化..操作符,那会是一个好主意,定义一个C函数用于连接字符串,例如 utils.concat(DIR/基地。扩展名)

In case Lua doesn't optimize the ".." operator, would it be a good idea to define a C function for concatenating strings, e.g. utils.concat(dir, "/", base, ".", extension)?

推荐答案

虽然Lua的关于执行 .. 使用一个简单的优化,你仍然应该小心地使用它一个紧密的循环,特别是加入非常大的字符串时,因为这将创造大量的垃圾,从而影响性能。

Although Lua performs a simple optimization on .. usage, you should still be careful to use it in a tight loop, especially when joining very large strings, because this will create lots of garbage and thus impact performance.

来连接许多字符串的最好方法是使用 表。 CONCAT

The best way to concatenate many strings is with table.concat.

table.concat 可让您使用一个表作为临时缓冲要连接所有的字符串,并执行,只有当完成添加字符串缓冲区中的串联,就像下面这个傻例如:

table.concat lets you use a table as a temporary buffer for all the strings to be concatenated and perform the concatenation only when you are done adding strings to the buffer, like in the following silly example:

local buf = {}
for i = 1, 10000 do
    local buf[#buf+1] = get_a_string_from_somewhere()
end
local final_string = table.concat( buf )


.. 的简单的优化可以看出分析下面的脚本的反汇编字节code:


The simple optimization for .. can be seen analyzing the disassembled bytecode of the following script:

-- file "lua_06.lua"

local a = "hello"
local b = "cruel"
local c = "world"

local z = a .. " " .. b .. " " .. c

print(z)

luac -l -p lua_06.lua 的输出如下(为lua 5.2.2):

the output of luac -l -p lua_06.lua is the following (for Lua 5.2.2):


main  (13 instructions at 003E40A0)
0+ params, 8 slots, 1 upvalue, 4 locals, 5 constants, 0 functions
    1   [3] LOADK       0 -1    ; "hello"
    2   [4] LOADK       1 -2    ; "cruel"
    3   [5] LOADK       2 -3    ; "world"
    4   [7] MOVE        3 0
    5   [7] LOADK       4 -4    ; " "
    6   [7] MOVE        5 1
    7   [7] LOADK       6 -4    ; " "
    8   [7] MOVE        7 2
    9   [7] CONCAT      3 3 7
    10  [9] GETTABUP    4 0 -5  ; _ENV "print"
    11  [9] MOVE        5 3
    12  [9] CALL        4 2 1
    13  [9] RETURN      0 1

您可以看到,只有一个 CONCAT 运算code产生,尽管许多 .. 运营商在脚本中使用。

You can see that only a single CONCAT opcode is generated, although many .. operators are used in the script.

要充分了解什么时候使用 table.concat 你必须知道,Lua的字符串的一成不变的。这意味着,只要你试图连接两个字符串,你确实是创建一个新的字符串(除非生成的字符串已经被国米preTER实习,但这是不可能的,通常)。例如,请考虑下面的代码片段:

To fully understand when to use table.concat you must know that Lua strings are immutable. This means that whenever you try to concatenate two strings you are indeed creating a new string (unless the resulting string is already interned by the interpreter, but this is usually unlikely). For example, consider the following fragment:

local s = s .. "hello"

和假设取值已经包含了一个巨大的字符串(例如,10MB)。执行该语句创建一个新的字符串(10MB + 5个字符),并丢弃旧的。所以你刚才创建的垃圾收集器,以应付一个10MB的死亡对象。如果你这样做,你反复最终霸占了垃圾收集器。这是 .. 实际问题,这是典型的使用情况下,有必要收集,最后一个字符串的各个部分在一个表中,并使用 table.concat 就可以了:这将无法避免垃圾的产生(所有的碎片的将会的调用表.concat ),但会大大降低的不必要的的垃圾。

and assume that s already contains a huge string (say, 10MB). Executing that statement creates a new string (10MB + 5 characters) and discards the old one. So you have just created a 10MB dead object for the garbage collector to cope with. If you do this repeatedly you end up hogging the garbage collector. This is the real problem with .. and this is the typical use case where it is necessary to collect all the pieces of the final string in a table and to use table.concat on it: this won't avoid the generation of garbage (all the pieces will be garbage after the call to table.concat), but you will greatly reduce unnecessary garbage.


  • 使用 .. 每当您连接数,可能是短,字符串,或者你是不是在一个紧密的循环。在这种情况下 table.concat 可以给你的更糟的性能,因为:

    • 您必须创建一个表(通常你会扔掉);

    • 您必须调用函数 table.concat (函数调用开销影响性能比使用更内置 .. 运营商几次)。

    • Use .. whenever you concatenate few, possibly short, strings, or you are not in a tight loop. In this case table.concat could give you worse performance because:
      • you must create a table (which usually you would throw away);
      • you have to call the function table.concat (the function call overhead impacts performance more than using the built-in .. operator a few times).

      • 您必须这样做在后续步骤(即 .. 优化只能同恩pression内);

      • 您是在一个紧凑的循环;

      • 的字符串是大(比如说,几个KBS或更多)。

      • you must do it in subsequent steps (the .. optimization works only inside the same expression);
      • you are in a tight loop;
      • the strings are large (say, several kBs or more).

      请注意,这些只是经验法则。在性能是最重要的真的,你应该配置您的code。

      Note that these are just rules of thumb. Where performance is really paramount you should profile your code.

      反正Lua是相当与字符串处理的时候,所以平时你不用管这么多。其他脚本语言比较快

      Anyway Lua is quite fast compared with other scripting languages when dealing with strings, so usually you don't need to care so much.

      这篇关于是否Lua的优化" .."运营商?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆