Lua性能优化Tips

作者: 白桦叶 | 来源:发表于2018-04-04 16:07 被阅读271次

    前言

    这是基于Lua官方文档总结(fan yi)出来的文章 -)

    关于Lua的属性

    1. Lua中每一个active的函数都有一个activation record,其数据结构是stack(当然其实现的数据结构仍然是数组),activation record保存该函数的Registers 寄存器,一个函数最多可以拥有250多个寄存器,因为指向寄存器的指针的只有8位(bit)。
    2. Lua 的Table里面包含2部分,一部分是array,一部分是hash,在1-n范围内的数据存储到array,在n之外的其他数据存储在hash,其中hash部分使用了 open address 开放寻址法。默认table的大小为0,当新key要加入,table大小从0->1,1->2,2->4 ...。 Table只有在rehash的情况也就是insert的情况下才会缩小shrink Table,这样实现基于两个原因,一是避免检查nil,二是允许循环中赋值nil。

    So, Lua traverses all entries, counting and
    classifying them, and then chooses as the size of the array part the largest power
    of 2 such that more than half the elements of the array part are filled. The hash
    size is then the smallest power of 2 that can accommodate all the remaining
    entries (that is, those that did not fit into the array part).

    1. Lua的字符串是内联( internalized)的,也就是说只保存一份字符串的拷贝,当新string出现,lua会检查是否存在这个字符串,有则复用。这样的做法有优点也有缺点,优点是方便字符串比较(比较指针是否相同即可),缺点是降低新建字符串的速度(要先查找字符串是否已经存在)。如上面所说,变量只是指向字符串。

    技巧

    技巧1 使用local变量

    使用local变量,以a = a+b为例子,a、b是全局变量时候和a、b是局部变量时候的比对如下

    a = a + b;
    
    GETGLOBAL 0 0 ; a
    GETGLOBAL 1 1 ; b
    ADD 0 0 1
    SETGLOBAL 0 0 ; a
    
    local a;
    local b;
    a = a +b;
    
    ADD 0 0 1
    

    很明显使用local 少了运行3次

    For instance, the code
    for i = 1, 1000000 do
    local x = math.sin(i)
    end
    

    比下方的写法慢30%

    local sin = math.sin
    for i = 1, 1000000 do
    local x = sin(i)
    end
    

    技巧2 Table

    为了减少Table rehash的次数,可直接使用构造方法直接赋值,如
    多次赋值

     local param = {};
    param.type = 1;
    param.id = 1;
    

    直接赋值,Lua能知道table需要容纳2个元素并且新建相应大小的table。

     local param = {type= 1, id = 1};
    

    技巧3 字符串

    使用table.concat连接字符串

    技巧4 复用

    这个适用于一个参数的方法调用,保存方法的计算结果,防止重复计算。

    function memoize (f)
      local mem = {} -- memoizing table
      setmetatable(mem, {__mode = "kv"}) -- make it weak
      return function (x) -- new version of ’f’, with memoizing
          local r = mem[x]
          if r == nil then -- no previous result?
            r = f(x) -- calls original function
            mem[x] = r -- store result for reuse
          end
        return r
      end
     end
    

    技巧5 垃圾回收

    Lua垃圾回收的速率是跟内存消耗的速率成正比。
    关于垃圾回收有两个接口Lua的collectgarbage和C的lua_gc,
    停止垃圾回收使用于批处理或者对时间敏感的程序当中

    参考链接

    Lua官方文档

    相关文章

      网友评论

        本文标题:Lua性能优化Tips

        本文链接:https://www.haomeiwen.com/subject/bnvbcftx.html