lua代码优化(转)

暂时转了别人一篇,以后再优化

1.使用局部变量local

这是最基础也是最有用的策略,虽然使用全局变量并不能完全避免,但还是应该尽量避免,取而代之使用局部变量即local。这里的局部变量也包括函数function,因为在Lua里函数也是一个变量。局部变量的存取会更快,而且在生命周期之外就会释放掉。

使用全局变量

CCX = display.contentCenterX  --global variable
for i = 1,100 do
   local image = display.newImage( "myImage" )
   image.x = CCX
end

使用局部变量

local CCX = display.contentCenterX  --local variable
for i = 1,100 do
   local image = display.newImage( "myImage" )
   image.x = CCX
end

这个原则也适用于Lua的核心库,比如math库。对于这类函数也应该使用局部变量。

非局部变量

local function foo( x )
   for i = 1,100 do
      x = x + math.sin(i)
   end
   return x
end

使用局部变量

local sin = math.sin  --local reference to math.sin
local function foo(x)
   for i = 1,100 do
      x = x + sin(i)
   end
   return x
end

最后,记住尽量用局部变量的方式来使用函数。当然,这样需要注意函数的作用域的问题。如果你对Lua的作用域还不够清楚,请看Understanding “SCOPE” for beginning programmers

使用全局的函数

function func1()
   func2( "myValue" )
end
function func2( y )
   print( y )
end
func1()

使用局部的函数

--"func2" properly scoped above "func1"
local function func2( y )
   print( y )
end
local function func1()
   func2( "myValue" )
end
func1()

2.避免将函数体定义作为其他函数的参数来使用

如果函数的参数是函数时,应将参数函数作为局部变量传进参数,而不要直接写函数定义,请看下面两个例子:

直接在参数表里定义函数

local func1 = function(a,b,func)
   return func(a+b)
end
for i = 1,100 do
   local x = func1( 1, 2, function(a) return a*2 end )
   print( x )
end

使用局部变量传参

local func1 = function( a, b, func )
   return func( a+b )
end
local func2 = function( c )
   return c*2
end
for i = 1,100 do
   local x = func1( 1, 2, func2 )
   print( x )
end

3.避免使用table.insert()

下面来看看4个实现表插入的方法。在4个方法之中table.insert()在效率上不如其他方法,是应该避免使用的。

使用table.insert

local a = {}
local table_insert = table.insert
for i = 1,100 do
   table_insert( a, i )
end

使用循环的计数

local a = {}
for i = 1,100 do
   a[i] = i
end

使用table的size

local a = {}
for i = 1,100 do
   a[#a+1] = i
end

使用计数器

local a = {}
local index = 1
for i = 1,100 do
   a[index] = i
   index = index+1
end

4.减少使用 unpack()函数

Lua的unpack()函数不是一个效率很高的函数。你完全可以写一个循环来代替它的作用。

使用unpack()

local a = { 100, 200, 300, 400 }
for i = 1,100 do
   print( unpack(a) )
end

代替方法

local a = { 100, 200, 300, 400 }
for i = 1,100 do
   print( a[1],a[2],a[3],a[4] )
end

5.缓存table的元素

缓存table的元素,特别是在循环内使用会提高效率。

未缓存

for i = 1,100 do
   for n = 1,100 do
      a[n].x = a[n].x + 1
      print( a[n].x )
   end
end

缓存

for i = 1,100 do
   for n = 1,100 do
      local y = a[n]
      y.x = y.x + 1
      print( y.x )
   end
end

6.避免使用ipairs()

当遍历table时,使用Lua的ipairs()的效率并不高。

使用ipairs()

local t1 = {}
local t2 = {}
local t3 = {}
local t4 = {}
local a = { t1, t2, t3, t4 }
for i,v in ipairs( a ) do
   print( i,v )
end

代替方法

local t1 = {}
local t2 = {}
local t3 = {}
local t4 = {}
local a = { t1, t2, t3, t4 }
for i = 1,#a do
   print( a[i] )
end

7.数学方法的效率比较

应该使用更快的数学方法。

避免对正数使用math.fmod()

--math.fmod method (discouraged)
local fmod = math.fmod
for i = 1,100 do
   if ( fmod( i,30 ) < 1 ) then
      local x = 1
   end
end
--modulus operator method (recommended)
for i = 1,100 do
   if ( ( i%30 ) < 1 ) then
      local x = 1
   end
end

乘法比除法快

x * 0.5 ; x * 0.125  --recommended
x/2 ; x/8            --discouraged

乘法比乘幂快

x * x * x  --recommended
x^3        --discouraged

8.保存Texture内存

Texture内存一般只有在出现警告时才会去关注,但那时就很难去补救了。

  1. 当texture不需要的时候记得释放掉。
  2. 如果你有一个525×600的背景图片,你可以改成448×512的。因为OpenGL对图片内存遵循2的倍数原则,即每次使用内存都是以2的倍数为长度的。所以525×600的图片将会消耗1024*1024的内存(即1024×1024 (pixels) × 4 (bytes) = 4,194,304 bytes = 4 MB),而448×512只会消耗1/4的内存。在图片清晰度容忍的情况下尽量缩小到下一个2倍量级内。
  3. 尽可能的重复利用素材。对于图片相同而颜色不同的可以使用setFillColor函数。例如你有红苹果和青苹果,那么你可以创建一个灰度的图片然后分别添加红色和绿色。
  4. 如果你使用image sheet,那么一定要使用类似TexturePacker的软件,不仅能提高开发效率也能优化图片大小。

9.预先创建物理对象

如果你要在场景中使用一定数量的物理对象,那么预先创建所有的对象会在使用时提高效率。那些暂时用不到的对象可以设置为未激活的状态然后放到屏幕的外面或者放到一个不可见的group里。当需要时设置对于的位置并激活即可。 实时创建物理对象并不是不可以,但一次性创建10-20个对象必然会造成性能问题,而导致顿卡延时等。 当然,也要考虑到内存的问题,如果一开始就创建几百个物体,那么对于内存的消耗就使得性能提高有点得不偿失了。

10.音频使用策略

有些音效是整个app都会用到的,这样的音效需要一开始就载入到内存中。对于音质并没有特别高的要求的音乐和音效需要考虑是否需要压缩,比如使用11khz来减小音频文件的大小,一般用户也听不出太大的区别,而这样减少的内存可是相当可观的。而且要使用简单的适合多平台的音频格式,比如WAV格式。 如果需要的话,音效可以如下组织成一个table,这样便于在使用时引用或者在不需要的时候释放掉。

--load these sounds during NON-time-critical code
local soundTable = {
   mySound1 = audio.loadSound( "a.wav" ),
   mySound2 = audio.loadSound( "b.wav" ),
   mySound3 = audio.loadSound( "c.wav" ),
   mySound4 = audio.loadSound( "d.wav" ),
   mySound5 = audio.loadSound( "e.wav" ),
   mySound6 = audio.loadSound( "f.wav" ),
   mySound7 = audio.loadSound( "g.wav" ),
   mySound8 = audio.loadSound( "h.wav" ),
}

播放一个音效就非常简单:

local mySound = audio.play( soundTable["mySound1"] )

永远不要忘记,当音效不需要的时候就要释放掉:

local ST = soundTable
for s,v in pairs(ST) do
   audio.dispose( ST[s] ) ; ST[s] = nil
end
时间: 2024-10-14 14:25:10

lua代码优化(转)的相关文章

cocos2dx lua中异步加载网络图片,可用于显示微信头像

最近在做一个棋牌项目,脚本语言用的lua,登录需要使用微信登录,用户头像用微信账户的头像,微信接口返回的头像是一个url,那么遇到的一个问题就是如何在lua中异步加载这个头像,先在引擎源码里找了下可能会提供这个功能的地方,发现好像没有提供类似功能,那么只能自己动手写.所以我在ImageView这个类里面添加了一个成员方法,其实可以不写在ImageView里,而且我觉得非必需情况下还是不要修改引擎源码的好,因为如果源码改动比较多的话,将来引擎版本升级会比较麻烦.我写在ImageView里纯粹是想偷

Lua 第一天

今天开始学习Lua语言,感觉Lua非常便捷.我用的编译器是SciTE,很不错. 举例一:无需引用,内置输出语句   print() print(6)   --> 6 print(type(6))  -->   number 举例二:对数字字符串进行数字化处理 print("2"+3 )  -->5 举例三:..连接俩个字符串,#返回字符串长度 举例四:print()输出函数,可以有多个输出值 a = 1,b =2,c = a+b    print(a,b,c,a,b,

lua协程一则报错解决“attempt to yield across metamethod/C-call boundary”

问题 attempt to yield across metamethod/C-call boundary 需求跟如下帖子中描述一致: http://bbs.chinaunix.net/forum.php?mod=viewthread&action=printable&tid=4065715 模拟一个场景,在C中创建出coroutine来执行Lua脚本,并且提供C API给Lua使用,当某些操作可能会阻塞时(如网络I/O),C函数中执行yield将协程切换出去,然后未来的某个时刻,如果条件

lua闭合函数

function count( ... ) local i = 0 return function( ... ) i = i+ 1 return i end end local func = count(...) print(func()) print(func()) print(func()) 结果如下: 1 2 3 [Finished in 0.1s] lua 闭合函数:一个函数加上该函数所需访问的所有“非局部变量”. 如上所示:count()函数返回了另一个函数,而这个函数使用了count

Mac下Lua Sublime Text2 开发环境搭建

1.安装Lua编译器 下载Lua, http://www.lua.org/: 解压后,cd进入该文件夹src目录下 在当前文件夹执行make macosx   然后回车 cd 到上一目录,执行sudo make install 完成之后执行lua -v 可以看到:Lua 5.3.3  Copyright (C) 1994-2016 Lua.org, PUC-Rio 2.安装Sublime Text2 1.下载http://sublime-text-2.cn.uptodown.com后打开: {

Nginx+Lua 积累

Nginx+Lua 积累 1.解析16进制编码的中文参数 复制代码 local encodeStr = "%E6%B0%94" local decodeStr = ""; for i = 2, #encodeStr - 1, 3 do local num = encodeStr:sub(i, i + 1); num = tonumber(num, 16); decodeStr = decodeStr .. string.char(num); end ngx.say(

nginx与Lua执行顺序

Nginx顺序 Nginx 处理每一个用户请求时,都是按照若干个不同阶段(phase)依次处理的,而不是根据配置文件上的顺序. Nginx 处理请求的过程一共划分为 11 个阶段,按照执行顺序依次是 post-read.server-rewrite.find-config.rewrite.post-rewrite. preaccess.access.post-access.try-files.content.log. post-read: 读取请求内容阶段 Nginx读取并解析完请求头之后就立即

在 Lua 里 使用 Cocos Studio 导出的 .csb 文件

1. 加载 节点到场景 第一种方法 local scene = cc.CSLoader:createNode("scene.csb") self:addChild(scene) 第二种方法 local scene = cc.uiloader:load("MainScene.csb"):addTo(self) 2.强转精灵类型 local sprite = tolua.cast(object,"cc.Sprite") CocoStudio 做的里面

代码优化(长期更新)

前言 代码优化,一个很重要的课题.可能有些人觉得没用,一些细小的地方有什么好修改的,改与不改对于代码的运行效率有什么影响呢?这个问题我是这么考虑的,就像大海里面的鲸鱼一样,它吃一条小虾米有用吗?没用,但是,吃的小虾米一多之后,鲸鱼就被喂饱了.代码优化也是一样,如果项目着眼于尽快无BUG上线,那么此时可以抓大放小,代码的细节可以不精打细磨:但是如果有足够的时间开发.维护代码,这时候就必须考虑每个可以优化的细节了,一个一个细小的优化点累积起来,对于代码的运行效率绝对是有提升的. 代码优化的目标是: