在竞争激烈的游戏行业中,尤其页游,面对策划复杂和频繁的需求,使用脚本能够减少难度和成本。在使用Lua的过程中,会常常訪问全局变量来作为配置文件。

在訪问全局变量时,能够通过局部变量引用全局变量来优化。当然,这种优化毫无意义。

Locals Vs Globals  from  http://lua-users.org/wiki/LocalsVsGlobals









Comparison between local and global variables:





Implementation: Locals index an array of registers on the stack, with hard-coded integer index (at least in the standard implementation -- LuaImplementations).

Globals index from a table (or userdata), typically with variable name string, stored as constant or variable, as the key.

实现:在Lua标准实现中,使用hard-code 整数索引在 registers on the stack 上索引局部变量。

在table或者userdata中,通过string常量或者string变量作为键来索引全局变量。

Performance: The above point implies that locals can be a bit faster

Still, table indexing is a fairly efficient operation in Lua (e.g. strings are interned with precomputed hash), so this point can often be ignored unless profiling indicates optimization is needed.

性能:通过实现不同,局部变量略微比全局变量速度快。

可是,在lua table中通过string来索引也是相当快。由于字符串在lua中被内化,事先计算过hash值。

所以,除非在剖析优化性能之外,性能问题能够被忽略。

Syntax: If an environment table is set, globals can be accessed in Lua code with or without explicitly naming the environment table they come from: foo, _G.foo, or getfenv().foo (or in 5.2.0work3, _ENV.foo). 

This allows different styles of environment usage, such as in ModuleDefinition.

语法:假设环境table是一个集合,在环境table之外能够通过foo,_G.foo 或者getfenv().foo来获取到全局变量。

可是,局部变量仅仅能在模块定义中获取到。

Scope: Locals are scoped within a lexical block. Globals are scoped within any number of functions assigned a given environment table at run-time.

作用域:局部变量的作用域在语法块中。在执行时,全局变量能够在不论什么环境table赋值的函数中获取。

Declaration: Locals must be explicitly declared, with local statement, to use them.

Globals can be accessed on-the-fly, even with variable name set at runtime

The list of locals is defined statically. The list of globals may be determined at run-time and can even change during program execution.

声明:局部变量必须通过明显的声明去定义和使用。

全部局部变量的声明都是静态的。

可是,全局变量能够在代码执行时,动态的訪问,甚至能够在执行时设置全局变量。

全部全局变量能够在执行时来决定,设置在代码执行过程中来改变全局变量。

Standard library access: The standard library is normally exposed to a chunk via globals.

标准库的訪问:全部Lua的标准库都是通过全局变量暴露给使用者。

Precedence: Locals override globals.

优先权:局部变量覆盖全局变量

Bytecode introspection: Globals are more visible in the bytecode.

Global get/sets become GETGLOBAL/SETGLOBAL opcodes with the given variable name.

It is possible to list all the globals read or written byte a compiled chunk。

Limit on number: There is a limit to the number of locals per function (MAXLOCALS, typically 200).

字节码内省:

全局变量在字节码中是能够看到的。通过制定的变量名称,获取或者设置全局变量变成了GETGLOBAL/SETGLOBAL 指令。

通过读取或者写入一个预编译好块能够罗列出全部的全局变量。

数量限制:

 每个函数中,局部变量的数量最大为200个。

 

 

Basic facts  from  Lua Performance Tips Roberto Ierusalimschy

Before running any code, Lua translates (precompiles) the source into an internal format.

This format is a sequence of instructions for a virtual machine, similar to machine code for a real CPU.

This internal format is then interpreted by C code that is essentially a while loop with a large switch inside, one case for each instruction.

    Lua在执行不论什么代码之前,Lua预编译源码成为内部字节码格式。

字节码格式就是虚拟机的序列化指定,类似于真正CPU的机器指令。

内部字节码格式通过C语言编写的解释器通过一个基础的while loop来不断的为每个指定运行switch。

Perhaps you have already read somewhere that, since version 5.0, Lua uses a register-based virtual machine. 

The “registers” of this virtual machine do not correspond to real registers in the CPU, because this correspondence would be not portable and quite limited in the number of registers available.

Instead, Lua uses a stack (implemented as an array plus some indices) to accommodate its registers. 

Each active function has an activation record, which is a stack slice where in the function stores its registers.

So, each function has its own registers2. 

Each function may use up to 250 registers, because each instruction has only 8 bits to refer to a register.

  自从5.0版本号,Lua使用一种register-based virtual machine 虚拟机。 “registers” 不依赖于CPU真正的指令,依赖CPU指正的registers因为registers数量限制将导致Lua的不能够移植。

相反,lua使用stack 来解决registers。每个函数最大有250个registers,由于每个指定唯独8为来运行register。

Given that large number of registers, the Lua precompiler is able to store all local variables in registers.

The result is that access to local variables is very fast in Lua. 

So, it is easy to justify one of the most important rules to improve the performance of Lua programs: use locals!

    依赖于大量的registers,Lua能够预编译所以的局部变量在registers中。所以,在Lua中訪问局部变量非常高速。

所以。在优化lua性能时,一个非常重要的原则是使用局部变量:使用局部变量。

If you need to squeeze performance out of your program, there are several

places where you can use locals besides the obvious ones. 

For instance, if you call a function within a long loop, you can assign the function to a local variable. For instance, the code

for i = 1, 1000000 do

local x = math.sin(i)

end

runs 30% slower than this one:

local sin = math.sin

for i = 1, 1000000 do

local x = sin(i)

end

測试代码:

module.lua 文件:

A =1

B =1

main.lua文件:

print("=================================")

require("module")

local A =A

local t1 =os.clock ()





for i=1,100000000 do

    A =2

end





local t2 =os.clock ()





print("通过局部变量来优化全局变量的訪问:"..(t2-t1))









local t1 =os.clock ()





for i=1,100000000 do

    B =2

end





local t2 =os.clock ()

print("直接訪问全局变量:"..(t2-t1))

print("=================================")





local t1 =os.clock ()

local sin = math.sin

for i = 1, 100000000 do

  local x = sin(i)

end

local t2 =os.clock ()

print("通过局部变量来优化全局变量的訪问:"..(t2-t1))

local t1=os.clock ()

for i=1,100000000 do

     x = math.sin(i)

end

local t2 =os.clock ()

print("直接訪问全局变量:"..(t2-t1))

測试结果:

=================================

通过局部变量来优化全局变量的訪问:0.825

直接訪问全局变量:1.961

=================================

通过局部变量来优化全局变量的訪问:7.017

直接訪问全局变量:10.264

使用Lua 局部变量来优化性能,同一时候比較局部变量和全局变量的更多相关文章

  1. 用好lua+unity,让性能飞起来——关于《Unity项目常见Lua解决方案性能比较》的一些补充

    <Unity项目常见Lua解决方案性能比较>,这篇文章对比了现在主流几个lua+unity的方案 http://blog.uwa4d.com/archives/lua_perf.html ...

  2. 用好lua+unity,让性能飞起来——luajit集成篇/平台相关篇

    luajit集成篇 大家都知道luajit比原生lua快,快在jit这三个字上. 但实际情况是,luajit的行为十分复杂.尤其jit并不是一个简单的把代码翻译成机器码的机制,背后有很多会影响性能的因 ...

  3. 用好lua+unity,让性能飞起来——lua与c#交互篇

    前言 在看了uwa之前发布的<Unity项目常见Lua解决方案性能比较>,决定动手写一篇关于lua+unity方案的性能优化文. 整合lua是目前最强大的unity热更新方案,毕竟这是唯一 ...

  4. C# 编译器对局部变量的优化

    C# 编译器对局部变量的优化 C# 的编译器可以对代码进行优化,所以,我们在写代码的时候,可以更多地考虑一下代码的易读性问题. 不考虑基本的对齐和换行美化.看一下局部变量优化问题. C# 示例代码 例 ...

  5. [经验] Win7减肥攻略(删文件不删功能、简化优化系统不简优化性能)

    [经验] Win7减肥攻略(删文件不删功能.简化优化系统不简优化性能) ☆心梦无痕☆ 发表于 2014-1-24 11:15:04 https://www.itsk.com/thread-316471 ...

  6. 使用Concurrency Visualizer优化性能

    Concurrency Visualizer: https://msdn.microsoft.com/en-us/library/dd537632.aspx?f=255&MSPPError=- ...

  7. Python禁用GC优化性能

    Python使用的(Garbage Collection, GC)机制是引用计数(Reference Count),其原理是为每一个内存对象进行引用计数,因此当有大量的对象新建或删除时,必须要进行大量 ...

  8. IOS 通过 代码 自定义cell(Cell的高度不一致)(优化性能)

    创建cell的步骤 1.新建一个继承自UITabelViewCell的类 2.重写 initWithStyle:ReuseIdentifier: 方法 添加所有需要显示的子控件(不需要设置子控件的数据 ...

  9. 【SQL Server 优化性能的几个方面】(转)

    转自:http://blog.csdn.net/feixianxxx/article/details/5524819     SQL Server 优化性能的几个方面 (一).数据库的设计 可以参看最 ...

随机推荐

  1. tomcat6-输入输出buffer设计

    之前写的一个ppt 搬到博客来

  2. php 审批流程管理

    1.流程管理的用法是什么样的? 2.怎么发起想要的流程? 3.审批的人要是怎么审批通过? 4.流程审核是不是要挨个走过? 一.要有数据库的内容的 肯定会有表的,首先就是用户表了,然后就是流程表,用户编 ...

  3. 设计模式(八)组合模式 Composite

    组合模式: 允许你将对象组合成树形结构来表现“整体/部分”层次结构.组合能让客户以一致的方式处理个别对象以及对象组合. 组合模式适用于创建复杂的对象,这个对象包含某些个别的对象以及这些对象的组合. 从 ...

  4. HDU——1596find the safest road(邻接矩阵+优先队列SPFA)

    find the safest road Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  5. java面试题之数据基本类型各占几个字节

    类型 位数 字节数 short 2*8 2 char 2*8 2 int 4*8 4 float 4*8 4 long 8*8 8 double 8*8 8

  6. PHP中的验证码类(完善验证码)

    运行结果: <!--vcode.class.php--> <?php class Vcode { private $width; //宽 private $height; //高 p ...

  7. 处理登录和cookie

    做法 1: 可以一步一步cookies,毫无疑问,这非常麻烦. import requests params = {'',''} r = requests.post('',params) r = re ...

  8. Pushlets的初始化陷阱

    Pushlets是在类名为Pushlet的servlet的init方法中进行初始化的.一般我们会在web.xml配置pushlet的时候,指定其servlet在Web应用启动时就进行初始化,即便这样, ...

  9. 【NOIP2016练习】T1 挖金矿(二分答案)

    题意: 思路:二分答案A 合法的答案 sigma(s[i][xi])/sigma(xi)>=a i<=m sigma(s[i][xi]-a*xi)>=0 对于每个i找到xi使s[i] ...

  10. poj 1410 Intersection 线段相交

    题目链接 题意 判断线段和矩形是否有交点(矩形的范围是四条边及内部). 思路 判断线段和矩形的四条边有无交点 && 线段是否在矩形内. 注意第二个条件. Code #include & ...