使用Lua 局部变量来优化性能,同一时候比較局部变量和全局变量
在竞争激烈的游戏行业中,尤其页游,面对策划复杂和频繁的需求,使用脚本能够减少难度和成本。在使用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 局部变量来优化性能,同一时候比較局部变量和全局变量的更多相关文章
- 用好lua+unity,让性能飞起来——关于《Unity项目常见Lua解决方案性能比较》的一些补充
<Unity项目常见Lua解决方案性能比较>,这篇文章对比了现在主流几个lua+unity的方案 http://blog.uwa4d.com/archives/lua_perf.html ...
- 用好lua+unity,让性能飞起来——luajit集成篇/平台相关篇
luajit集成篇 大家都知道luajit比原生lua快,快在jit这三个字上. 但实际情况是,luajit的行为十分复杂.尤其jit并不是一个简单的把代码翻译成机器码的机制,背后有很多会影响性能的因 ...
- 用好lua+unity,让性能飞起来——lua与c#交互篇
前言 在看了uwa之前发布的<Unity项目常见Lua解决方案性能比较>,决定动手写一篇关于lua+unity方案的性能优化文. 整合lua是目前最强大的unity热更新方案,毕竟这是唯一 ...
- C# 编译器对局部变量的优化
C# 编译器对局部变量的优化 C# 的编译器可以对代码进行优化,所以,我们在写代码的时候,可以更多地考虑一下代码的易读性问题. 不考虑基本的对齐和换行美化.看一下局部变量优化问题. C# 示例代码 例 ...
- [经验] Win7减肥攻略(删文件不删功能、简化优化系统不简优化性能)
[经验] Win7减肥攻略(删文件不删功能.简化优化系统不简优化性能) ☆心梦无痕☆ 发表于 2014-1-24 11:15:04 https://www.itsk.com/thread-316471 ...
- 使用Concurrency Visualizer优化性能
Concurrency Visualizer: https://msdn.microsoft.com/en-us/library/dd537632.aspx?f=255&MSPPError=- ...
- Python禁用GC优化性能
Python使用的(Garbage Collection, GC)机制是引用计数(Reference Count),其原理是为每一个内存对象进行引用计数,因此当有大量的对象新建或删除时,必须要进行大量 ...
- IOS 通过 代码 自定义cell(Cell的高度不一致)(优化性能)
创建cell的步骤 1.新建一个继承自UITabelViewCell的类 2.重写 initWithStyle:ReuseIdentifier: 方法 添加所有需要显示的子控件(不需要设置子控件的数据 ...
- 【SQL Server 优化性能的几个方面】(转)
转自:http://blog.csdn.net/feixianxxx/article/details/5524819 SQL Server 优化性能的几个方面 (一).数据库的设计 可以参看最 ...
随机推荐
- day01_12.字符串
1.字符转义 在字符串中,出现一些比较特殊的字符,容易引起歧义 我们需要转义这些引起歧义的字符串 <?php $a = 'ab\\c'; //转义字符2个 \' \\ $b = 'ab\'c'; ...
- jqery实现一个图标上下滑动效果
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...
- linuxlinux0.11源码学习——bootsect.s学习
由于一直想写一个自己的操作系统,网上推荐了<linux内核完全注释>.自学了一个星期,感觉这本书还是很好的,同时写下关于内核代码的理解,如果有什么不对的对方,欢迎大家一起来交流. 在内核引 ...
- C++程序在Windows平台上各种定位内存泄漏的方法,并对比了它们的优缺点
一.前言 在Linux平台上有valgrind可以非常方便的帮助我们定位内存泄漏,因为Linux在开发领域的使用场景大多是跑服务器,再加上它的开源属性,相对而言,处理问题容易形成“统一”的标准.而在W ...
- tcpdump 进行抓包
tcpdump 进行抓包是怎么回事? tcp抓包是怎么搞的?
- PHP允许AJAX跨域请求的两种方法
* 一. 服务端设置 header 头允许AJAX跨域 ** 代码如下: // 允许 ityangs.net 发起的跨域请求 header("Access-Control-Allow-Ori ...
- UVA 10131 Is Bigger Smarter?(DP最长上升子序列)
Description Question 1: Is Bigger Smarter? The Problem Some people think that the bigger an elepha ...
- POJ3067 Japan
Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 26270 Accepted: 7132 Description Japa ...
- vue 上传文件 和 下载文件
Vue上传文件,不必使用什么element 的uplaod, 也不用什么npm上找的个人写的包,就用原生的Vue加axios就行了, 废话不多说,直接上代码:html: <input type= ...
- hdu 3189(网络流+二分枚举)
Steady Cow Assignment Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6422 Accepted: ...