zoukankan      html  css  js  c++  java
  • 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
    
  • 相关阅读:
    cube.js 基于http 通道的数据实时更新bug 解决
    cube.js 基于http 通道的数据实时更新
    cube.js websocket 实时数据更新说明
    phpspy 进行php 项目性能分析
    使用groovy 下载maven依赖包
    java 几个不错的代码生成工具
    语言性能分析工具总结
    使用rbspy 分析ruby应该性能
    dremio v18.0 软件包可以使用了
    nginx rewrite查询字符串重写问题
  • 原文地址:https://www.cnblogs.com/zhangfeitao/p/4503713.html
Copyright © 2011-2022 走看看