zoukankan      html  css  js  c++  java
  • lua的性能优化

    Roberto Ierusalimschy写过经典的Lua 性能提示的文章,链接地址>>

    我通过实际的代码来验证,发现一个问题。当我使用 LuaStudio 运行时,发现结果反而与提示相反,甚是奇怪,而使用luac进行运行,与作者给予的提示相符,在某些地方性能可能有优化,比如读取35kb的文件时,时间还是比较快的(可能5.1版本做过优化了)。

    日常的Lua编码中,需要注意以下几点:

    1)多使用local

    print(_VERSION)
    
    local startTime, endTime
    
    
    startTime = os.clock()
    
    for i = 1, 100 * 10000 do
        local x = math.sin(i)
    end
    
    endTime = os.clock()
    
    print("[local] used time " .. (endTime - startTime) * 1000 .. " ms")
    
    
    
    startTime = os.clock()
    
    local sin = math.sin
    for i = 1, 100 * 10000 do
        local x = sin(i)
    end
    
    endTime = os.clock()
    
    print("[local] used time " .. (endTime - startTime) * 1000 .. " ms")

    image

    上面二段代码,唯一的区别就是使用 local sin 将 math.sin缓存起来。性能提升约 (107 - 74) / 107 ~= 30.8%,基本符合作者所说的30%的效率提升。

    startTime = os.clock()
    function foo(x)
        for i = 1, 100 * 10000 do
            x = x + math.sin(i)
        end
        return x
    end
    
    foo(10)
    
    endTime = os.clock()
    
    print("[foo] used time " .. (endTime - startTime) * 1000 .. " ms")
    
    
    startTime = os.clock()
    function foo2(x)
        local sin = math.sin
        for i = 1, 100 * 10000 do
            x = x + sin(i)
        end
        return x
    end
    
    foo2(10)
    
    endTime = os.clock()
    
    print("[foo2] used time " .. (endTime - startTime) * 1000 .. " ms")

    image

    提升的时间是 (125 – 88) /125 = 29.6%,也约为30%(需要多次测试取平均值)

    使用闭包,避免动态编译。

    startTime = os.clock()
    local lim = 10 * 10000
    local a = {}
    for i = 1, lim do
        a[i] = loadstring(string.format("return %d", i))
    end
    
    print(a[10]())
    
    endTime = os.clock()
    
    print("used time " .. (endTime - startTime) * 1000 .. " ms")
    
    
    
    
    startTime = os.clock()
    function fk(k)
        return function() return k end
    end
    
    local lim = 10 * 10000
    local a = {}
    for i = 1, lim do
        a[i] = fk(i)
    end
    endTime = os.clock()
    
    print("used time " .. (endTime - startTime) * 1000 .. " ms")

    image

    节省了约92%的时间,差异距大。

    2) 字符串拼接,尽可能使用 table 替代

    startTime = os.clock()
    
    local buff = ""
    for line in io.lines("C:/Users/zhangyi/Desktop/xxx.txt") do
        buff = buff .. line .. "
    "    
    end
    
    endTime = os.clock()
    
    print(collectgarbage("count") * 1024)
    
    print("used time " .. (endTime - startTime) * 1000 .. " ms")
    
    
    
    
    startTime = os.clock()
    
    local buff = ""
    local tbl = {}
    for line in io.lines("C:/Users/zhangyi/Desktop/xxx.txt") do
        table.insert(tbl, line)
    end
    
    buff = table.concat(table, "
    ")
    
    endTime = os.clock()
    
    print(collectgarbage("count") * 1024)
    
    print("used time " .. (endTime - startTime) * 1000 .. " ms")

    image

    差异非常大,无论是内存还是时间,主要原因是:Lua中字符串的拼接都是新创建一个新的字符串,有一个新创建一块内存、copy字符串的动作,时间、空间上消耗都比较大。

    3) table使用的优化

    startTime = os.clock()
    for i = 1, 100 * 10000 do
        local a = {}
        a[1] = 1
        a[2] = 2
        a[3] = 3
    end
    endTime = os.clock()
    
    print("used time " .. (endTime - startTime) * 1000 .. " ms")
    
    
    startTime = os.clock()
    for i = 1, 100 * 10000 do
        local a = {true, true, true}
        a[1] = 1
        a[2] = 2
        a[3] = 3
    end
    endTime = os.clock()
    
    print("used time " .. (endTime - startTime) * 1000 .. " ms")
    image

    时间相差一倍,也就是说如果不给{}给定初时化大小,当赋值的时候,它会申请空间来存放相应的值。

    local polyline= {}
    
    for i = 0, 100 * 10000 do
        table.insert(polyline, {x = i, y = 1})
    end
    
    print(collectgarbage("count") / 1024)

    107.57151889801MB

    local polyline= {}
    
    for i = 0, 100 * 10000 do
        table.insert(polyline, {i, 1})
    end
    
    print(collectgarbage("count") / 1024)

    77.053853034973MB

    local polyline= {
        x = {},
        y = {}
    }
    
    for i = 0, 100 * 10000 do
        table.insert(polyline.x, i)
        table.insert(polyline.y, i)
    end
    
    print(collectgarbage("count") / 1024)

    32.019150733948MB

    空间占用差距也非常大,从上面似乎可以得到这样的结论:尽可能减少table的长度,尽可能使用array 而不是 hash。

    综上所述,尽可能多使用local,减少查询的性能损耗。json数据表如果需要转化为table时,改变数据的存储结构可能减少很大的内存使用。

  • 相关阅读:
    【JavaP6大纲】Java基础篇:为什么jdk8以后HashMap会使用红黑树优化?
    【JavaP6大纲】Java基础篇:HashMap加载因子为什么是0.75?
    【JavaP6大纲】Zookeeper篇:选举机制
    就是要幸福(1)严于律人
    天真的童年
    闲言碎语话心得垃圾工作
    镜花水月
    就是要幸福(3)言行自由
    五年
    爸爸我给你捂捂手
  • 原文地址:https://www.cnblogs.com/meteoric_cry/p/8000948.html
Copyright © 2011-2022 走看看