2024-05-08

lua 相关

  1. 嵌入式语言 [脚本语言]

c# object返回给lua,是通过dictionary将lua的userdata和c# object关联起来,只要lua中的userdata没回收,c# object也就会被这个dictionary拿着引用,导致无法回收。

用好Lua+Unity,让性能飞起来——Lua与C#交互篇_unity为什么放弃lua-CSDN博客

uajit的两种运行模式:jit、interpreter

jit模式:这是luajit高效所在,简单地说就是直接将代码编译成机器码级别执行,效率大大提升(事实上这个机制没有说的那么简单,下面会提到)。然而不幸的是这个模式在ios下是无法开启的,因为ios为了安全,从系统设计上禁止了用户进程自行申请有执行权限的内存空间,因此你没有办法在运行时编译出一段代码到内存然后执行,所以jit模式在ios以及其他有权限管制的平台(例如ps4,xbox)都不能使用。

interpreter模式:那么没有jit的时候怎么办呢?还有一个interpreter模式。事实上这个模式跟原生lua的原理是一样的,就是并不直接编译成机器码,而是编译成中间态的字节码(bytecode),然后每执行下一条字节码指令,都相当于swtich到一个对应的function中执行,相比之下当然比jit慢。但好处是这个模式不需要运行时生成可执行机器码(字节码是不需要申请可执行内存空间的),所以任何平台任何时候都能用,跟原生lua一样。这个模式可以运行在任何luajit已经支持的平台,而且你可以手动关闭jit,强制运行在interpreter模式下。

我们经常说的将lua编译成bytecode可以防止破解,这个bytecode是interpreter模式的bytecode,并不是jit编译出的机器码(事实上还有一个在bytecode向机器码转换过程中的中间码SSA IR,有兴趣可以看luajit官方wiki),比较坑的是可供32位版本和64位版本执行的bytecode还不一样,这样才有了著名的2.0.x版本在ios加密不能的坑。

首先所有的lua都会被编译成bytecode,在interpreter模式下执行,当interpreter发现某段代码经常被执行,比如for循环代码(是的,大部分性能瓶颈其实都跟循环有关),那么luajit会开启一个记录模式,记录这段代码实际运行每一步的细节(比如里头的变量是什么类型,猜测是数值还是table)。有了这些信息,luajit就可以做优化了:如果a+b发现就是两个数字相加,那就可以优化成数值相加;如果a.xxx就是访问a下面某个固定的字段,那就可以优化成固定的内存访问,不用再走表查询。最后就可以将这段经常执行的代码jit化。
这里可以看到,第一,interpreter模式是必须的,无论平台是否允许jit,都必须先使用interpreter执行;第二,并非所有代码都会jit执行,仅仅是部分代码会这样,并且是运行过程中决定的。

借助ffi,进一步提升luajit与c/c#交互的性能
ffi是luajit独有的一个神器,用于进行高效的luajit与c交互。其原理是向luajit提供c代码的原型声明,这样luajit就可以直接生成机器码级别的优化代码来与c交互,不再需要传统的lua api来做交互。
我们进行过简单的测试,利用ffi的交互效率可以有数倍甚至10倍级别的提升(当然具体要视乎参数列表而定),真可谓飞翔的速度。
而借助ffi也是可以提高luajit与c#交互的性能。原理是利用ffi调用自己定义的c函数,再从c函数调用c#,从而优化掉luajit到c这一层的性能消耗,而主要留下c到c#的交互消耗。在上一篇中我们提到的300ms优化到200ms,就是利用这个技巧达到的。
必须要注意的是,ffi只有在jit开启下才能发挥其性能,如果是在ios下,ffi反而会拖慢性能。所以使用的时候必须要做好快关。

(1) GameObject类:其实只是一个放在_G表中供人调用的一个充当索引的表,我们通过它来触发GameObject元表的各种元方法,实现对c#类的使用。
(2) GameObject的实例:是一个fulluserdata,内容为一个整数,这个整数代表了这个实例在objects表中的索引(objects是一个用list实现的回收链表,lua中调用的c#类实例都存在这个里面,后面会讲这个objects表),每次在lua中调用一个c#实例的方法时,都会通过这个索引找到这个索引在c#中对应的实例,然后进行操作,最后将操作结果转化为一个fulluserdata(或lua的内建类型,如bool等)压栈,结束调用。

lua中调用和创建的c#实例实际都是存在c#中的objects表中,lua中的变量只是一个持有该c#实例索引位置的fulluserdata,并没有直接对c#实例进行引用。

2 元表 及 元方法

1.在表中查找,如果找到,返回该元素,找不到则继续
2.判断该表是否有元表,如果没有元表,返回 nil,有元表则继续。
3.判断元表有没有__index 方法,如果 __index 方法为 nil,则返回 nil;如果__index 方法是一个表,则重复 1、2、3;如果 __index 方法是一个函数,则返回该函数的返回值。

元表可以定义一个table在遇到未知操作(元方法)时的行为,对于a和b两个table,是无法进行相加操作(a + b)。

rawset/rawget:对”原始的”表进行直接的赋值/取值操作。当操作table时,如果我们有以下需求:
访问时,不想从 __index 对应的元方法中查询值
更新时,不想执行 __newindex 对应的元方法
在 __newindex 元方法中,设置table的key/value时,不想陷入死循环而爆栈

  1. 闭包
    Lua编译一个函数时,其中包含了函数体对应的虚拟机指令、函数用到的常量值(数,文本字符串等等)和一些调试信息。
    在运行时,每当Lua执行一个形如function…end这样的函数时,它就会创建一个新的数据对象,其中包含但不只限于相应函数原型的引用和一个由所有upvalue引用组成的数组,而这个数据对象就称为闭包。
    函数是编译期概念,是静态的,而闭包是运行期概念,是动态的。

upvalue
upvalue可以简单理解为就是上个例子中foo1能使用到的val,单独拿出来是因为upvalue需要深入了解一下,从原理到使用都有很多需要注意的地方,也是闭包和函数一个比较大的区别,这里只说使用,原理实现分析在另一篇文章。
upvalue可以在内部函数之间共享,即 upvalue 提供一种闭包之间共享数据的方法:

lua[闭包]是Lua函数生成的数据对象。每个闭包可以有一个upvalue值,或者多个闭包共享一个upvalue数值。

使用ipairs 迭代器材遍历:
1.将所有table中的key值排列。

     2.找到key唯1的索引。

     3.向后递增1,如果key值不存在,则结束遍历。

     总结: 这种迭代器是用用来遍历数组的

使用pairs 迭代器遍历:
1.将所有table中的key值排列

     2.遍历table中的所有key值

     总结:这种迭代器是用来遍历字典的
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容