使用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 优化性能的几个方面 (一).数据库的设计 可以参看最 ...
随机推荐
- doc下设置永久环境变量的好方法
http://www-2w.blog.163.com/blog/static/97931518201021211123267/ 需要查看命令具体实现:setx machine “%path%”. 配置 ...
- ruby操作mysql
require "win32ole" require 'pathname' require 'mysql2' excel = WIN32OLE.new('excel.applica ...
- iOS--app自定义相册--从自定义的相册中获取图片
一.获取单张图片 思路: 1.利用UIImagePickerController可以从系统自带的App(照片\相机)中获得图片 2.设置代理,遵守代理协议 注意这个UIImagePickerContr ...
- Welcome-to-Swift-13继承(Inheritance)
一个类可以继承(inherit)另一个类的方法(methods),属性(property)和其它特性.当一个类继承其它类时,继承类叫子类(subclass),被继承类叫超类(或父类,superclas ...
- 【Luogu】P3745期末考试(三分)
题目链接 我是怎么把“期末考试”在本地写成“假期计划”的 qwq???? 本题把学生和卷子都排个序,按出成绩最晚时间三分. 三分之后可以O(n)的时间统计答案,因为修改卷子出成绩的时间可以贪心计划. ...
- BZOJ1227 [SDOI2009]虔诚的墓主人 【树状数组】
题目 小W 是一片新造公墓的管理人.公墓可以看成一块N×M 的矩形,矩形的每个格点,要么种着一棵常青树,要么是一块还没有归属的墓地.当地的居民都是非常虔诚的基督徒,他们愿意提前为自己找一块合适墓地.为 ...
- 我最喜欢的XML(三种方式)
我最喜欢的方式 下面的三个 XML 文档包含完全相同的信息: 第一个例子中使用了 date 属性: <note date="08/08/2008"> <to> ...
- java面试题之Error和Exception的区别
从概念角度分析: Error:程序无法处理的系统错误,编译器不做检查: Exception:程序可以处理的异常,捕获后可能恢复: 总结:前者是程序无法处理的错误,后者是可以处理的异常. 从责任角度分析 ...
- 富文本编辑器quill---vue组件(vue-quill-editor)的使用
1.配置webpack plugin 解决以下报错 Uncaught TypeError: Cannot read property 'imports' of undefined (image-res ...
- python输出字典中的中文
如果不用本文指定的方法,会有如下报错: UnicodeDecodeError: 'utf8' codec can't decode byte 0xbf in position 2: invalid s ...