• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • vbs
  • DOS/BAT
  • hta/htc
  • python
  • perl
  • VBA
  • ColdFusion
  • ruby
  • PowerShell
  • Lua
  • Golang
  • linux shell
您的位置:首页 > 脚本语言 >Lua > Lua性能优化技巧(五):削减、重用和回收

Lua性能优化技巧(五):削减、重用和回收

作者:junjie 字体:[增加 减小] 来源:互联网

junjie 通过本文主要向大家介绍了lua性能优化,lua性能,lua脚本优化,lua代码优化,lua 优化等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com

当处理Lua资源时,我们也应该遵循提倡用于地球资源的3R原则——Reduce, Reuse and Recycle,即削减、重用和回收。

削减是最简单的方式。有很多方法可以避免使用新的对象,例如,如果你的程序使用了太多的表,可以考虑改变数据的表述形式。一个最简单的例子,假设你的程序需要操作折线,最自然的表述形式是:

polyline =
{
    { x = 10.3, y = 98.5 },
    { x = 10.3, y = 18.3 },
    { x = 15.0, y = 98.5 },
    --...
}
</div>
尽管很自然,这种表述形式对于大规模的折线来说却不够经济,因为它的每个点都需要用一个表来描述。第一种替代方式是使用数组来记录,可以省点内存:

polyline =
{
     { 10.3, 98.5 },
     { 10.3, 18.3 },
     { 15.0, 98.5 },
     --...
}
</div>
对于一个有一百万个点的折线来说,这个修改可以把内存占用从95KB降低到65KB。当然,你需要在可读性上付出代价:p[i].x比p[i][1]更易懂。

另一个更经济的做法是使用一个数组存储所有x坐标,另一个存储所有y坐标:
polyline =
{
    x = { 10.3, 10.3, 15.0, ...},
    y = { 98.5, 18.3, 98.5, ...}
}
</div>
原有的
p[i].x
</div>
现在变成了
p.x[i]
</div>
使用这种表述形式,一百万个点的折线的内存占用降低到了24KB。

循环是寻找降低垃圾回收次数的机会的好地方。例如,如果在循环里创建一个不会改变的表,你可以把它挪到循环外面,甚至移到函数外作为上值。试对比:

function foo (...)
     for i = 1, n do
          local t = {1, 2, 3, "hi"}
          -- 做一些不会改变t表的事情
          --...
     end
end
</div>
和
local t = {1, 2, 3, "hi"} -- 创建t,一劳永逸
function foo (...)
    for i = 1, n do
        --做一些不会改变t表的事情
        --...
    end
end
</div>
相同的技巧亦可用于闭包,只要你不把它们移到需要它们的作用域之外。例如下面的函数:

function changenumbers (limit, delta)
    for line in io.lines() do
        line = string.gsub(line, "%d+", function (num)
            num = tonumber(num)
            if num >= limit then return tostring(num + delta) end
            -- 否则不返回任何值,保持原有数值
        end)
        io.write(line, "\n")
    end
end
</div>
我们可以通过将内部的函数移到循环外面来避免为每次迭代创建新的闭包:

function changenumbers (limit, delta)
    local function aux (num)
        num = tonumber(num)
        if num >= limit then return tostring(num + delta) end
    end
    for line in io.lines() do
        line = string.gsub(line, "%d+", aux)
        io.write(line, "\n")
    end
end
</div>
但是,我们不能把aux移到changenumbers函数之外,因为aux需要访问limit和delta。

对于多种字符串处理,我们可以通过使用现有字符串的索引来减少对创建新字符串的需要。例如,string.find函数返回它找到指定模式的位置索引,而不是匹配到的字符串。通过返回索引,它避免了在成功匹配时创建新的字符串。当有必要时,程序员可以通过调用string.sub来获取匹配的子串[1]。

当我们无法避免使用新的对象时,我们依然可以通过重用来避免创建新的对象。对于字符串来说,重用没什么必要,因为Lua已经为我们做了这样的工作:它总是将所有用到的字符串内部化,并在所有可能的时候重用。然而对于表来说,重用可能就非常有效。举一个普遍的例子,让我们回到在循环里创建表的情况。这一次,表里的内容不再是不变的。通常我们可以在所有迭代中重用这个表,只需要简单地改变它的内容。考虑如下的代码段:
local t = {}
for i = 1970, 2000 do
    t[i] = os.time({year = i, month = 6, day = 14})
end
</div>
下面的代码是等同的,但是重用了这张表:
local t = {}
local aux = {year = nil, month = 6, day = 14}
for i = 1970, 2000 do
    aux.year = i
    t[i] = os.time(aux)
end
</div>
实现重用的一个尤其有效的方式是缓存化[2]。基本思想非常简单,将指定输入对应的计算结果存储下来,当下一次再次接受相同的输入时,程序只需简单地重用上次的计算结果。

LPeg,Lua的一个新的模式匹配库,就使用了一个有趣的缓存化处理。LPeg将每个模式字符串编译为一个内部的用于匹配字符串的小程序,比起匹配本身而言,这个编译过程开销很大,因此LPeg将编译结果缓存化以便重用。只需一个简单的表,以模式字符串为键、编译后的小程序为值进行记录。

使用缓存化时常见的一个问题是,存储计算结果所带来的内存开销大过重用带来的性能提升。为了解决这个问题,我们可以在Lua里使用一个弱

您可能想查找下面的文章:

  • Lua性能优化技巧(六):最后的提示
  • Lua性能优化技巧(五):削减、重用和回收
  • Lua性能优化技巧(四):关于字符串
  • Lua性能优化技巧(三):关于表
  • Lua性能优化技巧(二):基本事实
  • 编写高性能Lua代码的方法

相关文章

  • Lua中字符串(string)浅析
  • Lua文件读写详解
  • 举例讲解Lua中的Table数据结构
  • Lua教程(二十一):编写C函数的技巧
  • Lua 中 pairs 和 ipairs 的区别
  • Lua的协程(coroutine)简介
  • Redis教程(三):List数据类型
  • 深入解读Lua中迭代器与泛型for的使用
  • Cocos2d-x中调用Lua及HelloWorld.lua源码分解
  • Lua编程中的一些基本语法整理

文章分类

  • vbs
  • DOS/BAT
  • hta/htc
  • python
  • perl
  • VBA
  • ColdFusion
  • ruby
  • PowerShell
  • Lua
  • Golang
  • linux shell

最近更新的内容

    • Lua之协同程序coroutine代码实例
    • Lua table中安全移除元素的方法
    • 把Lua函数传递到C/C++中实例
    • Lua中table库函数方法介绍
    • Lua中函数与面向对象编程的基础知识整理
    • 实例讲解Lua中pair和ipair的区别
    • Lua的堆栈浅析
    • Lua教程(四):在Lua中调用C语言、C++的函数
    • Lua编程示例(七):协同程序基础逻辑
    • Lua面向对象之多重继承、私密性详解

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有