Luajit 概述「建议收藏」

整理了下luajit 相关内容,分为了几部分,每部分最后是参考的blog地址。有兴趣的可以详细阅读原文。 一、JIT即时编译器 JIT:即时编译器。将频繁执行的代码,通过JIT编译器编译成机器码缓存起来,下次再调用时直接执行机器码。相比与原生Lua的逐条执行虚拟机指令效率更高。对于那些只执行一次的代码,则保持于原生Lua一样,逐条执行。JIT带来的效率提升,并不一定能抵消编译效率的下降。 当虚拟机执行指令时并不会立刻用JIT进行编译。只有部分指令需要JIT进行编译,JIT将决定那些代码将被编译。延迟编译有助于JIT选择一个最优的解决方案,进行决策。 可参考javajit:
https://blog.csdn.net/sunxianghuang/article/details/52094859
二、Luajit性能优化 1.使用ffi实现数据结构,减少内存消耗,避免hash重构。 2.用ffi调用C函数,ffi中会声明函数原型包含参数返回值的类型,jit可以直接生成机器码,从而实现对c函数调用的无缝对接,消除了对Lua虚拟堆栈的操作。 https://www.cnblogs.com/zwywilliam/p/5992737.html
三、Luajit 和Lua区别: hash算法不一样,导致表的遍历顺序不同。 Luajit中新增了一些转义字符,并且处理转义字符的方式也不一样。 Luajit内存上线是4G 函数中的局部变量最大限制Luajit要小于Lua Luajit不够稳定,在ios上不支持JIT功能 https://blog.csdn.net/linuxheik/article/details/53201217
四、Luajit API 1.ffi.new ffi.typeof :构造C数据 数据是垃圾回收的 local Num — 构造一个基础类型 Num = ffi.new‘int’, 20) — 构造基础类型数组 Num = ffi.new‘int[1]’,20) — 变长数组 Num = ffi.new‘int[?]’,10,2,20) — ?是占位符号 int[10] — 定义一个ctype local CType = ffi.typeof“int”) — ffi.new‘int’) 等价于 ffi.new ffi.typeof“int”) ) Num = CType10)
2.ffi.cast:lua类型转换成CType类型 local LuaStr = “abc” local CStr = ffi.cast“const char*”,LuaStr)
3.ffi.metatype:为c数据结构绑定元表 ffi.cdef[[ typedef struct { double x, y; } point_t; ]]
local point local mt = {
__add = functiona, b) return pointa.x+b.x, a.y+b.y) end, __len = functiona) return math.sqrta.x*a.x + a.y*a.y) end, __index = {
area = functiona) return a.x*a.x + a.y*a.y end, }, } point = ffi.metatype“point_t”, mt) –point = ffi.metatype“point_t”, {}) — wrong 调用了metatype后 point_t的元表不可再更改 local a = point3, 4) printa.x, a.y) –> 3 4 print#a) –> 5 printa:area)) –> 25 local b = a + point0.5, 8) print#b) –> 12.5
4.cdata = ffi.gccdata, finalizer):为 cdata设置析构函数,当cdata不在被其他对象引用时触发。
5.ffi.sizeof:返回Cdata内存大小 print ffi.sizeof“int[?]”,10) ) –> sizeofint) * 10 = 40
6.ffi.alignof:返回内存ctype内存对齐最小字节 ffi.cdef[[ typedef struct { int y; double x; } point_t; ]] print ffi.alignof“point_t”) )
7.ffi.offsetof:返回ctype结构体中 x字段的字节偏移量 print ffi.offsetof“point_t”, “x”) ) –>8
8.ffi.istype:判断cdata是否是ctype类型 是返回true local Point = ffi.new“point_t”) print ffi.istype“point_t”, Point) ) –>true
9.str = ffi.stringptr [,len]):ctype<const char*> 转 lua string local LuaStr = “abc” local CStr = ffi.cast“const char*”,LuaStr) — lua string 转 ctype<const char*> LuaStr = nil LuaStr = ffi.stringCStr) — ctype<const char*> 转 lua string printLuaStr) –> abc http://wiki.jikexueyuan.com/project/openresty/lua/FFI.html
五、ffi基本用法: (1)、调用C函数(提高函数执行效率) 1.C标准库中函数 local ffi = require“ffi”)ffi.cdef[[
int printfconst char *fmt, …);
]]ffi.C.printf“Hello %s!”, “world”) 首先 require“ffi”) 加载ffi库,然后声明函数,最后表用函数
2.调用其他库函数 在调用函数前先 ffi.load库名,[])加载库,C标准库是默认加载的不需要手动load。 3.调用C/C++自定义函数 在C/C++中声明函数时 添加 extern “C” __declspecdllexport)修饰函数。
ffi只可在lua中调用C/C++中的导出函数,也就是库函数或extern “C” __declspecdllexport)修饰的自定义函数。
(2)、在Lua中使用C结构体(减少内存开销) ffi.cdef [[ typedef struct MyStruct{char a; char b;} Point; ]] local point = ffi.new“Point”) printffi.sizeofpoint)) 定义结构体,并不需要要在C/C++中定义,只需在Lua中定义即可。构造一个对象。printffi.sizeofpoint)) = 2 point占用两个字节。

  • Lua 可以使用 ffi.new 初始化一个 cdata 对象,也可以使用 ffi.typeof 生成的类型来初始化一个 cdata 对象,在创建数组时应使用ffi.typeof 只生成一次类型重复使用这样效率更高。
  • 对于基本类型和字符串类型,没有必要将其转为 cdata 对象,其可以作为参数传入 C 函数中。也可以接收 C 函数的返回值
  • 对于基本类型指针对象,可以使用单元素数组进行初始化,可以使用数组元素赋值的方式改变其中的值
  • 对于结构类型,可以传入 C 指针参数,也可以传入 C 普通参数。对结构类型的操作,与 table 的字典操作类似


https://blog.csdn.net/alexwoo0501/article/details/50636785

Published by

风君子

独自遨游何稽首 揭天掀地慰生平

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注