Luajit 概述「建议收藏」

Luajit 概述「建议收藏」一、JIT即时编译器JIT:即时编译器。将频繁执行的代码,通过JIT编译器编译成机器码缓存起来,下次再调用时直接执行机器码。相比与原生Lua的逐条执行虚拟机指令效率更高。对于那些只执行一次的代码,则保持于原生Lua一样,逐条执行。JIT带来的效率提升,并不一定能抵消编译效率的下降。当虚拟机执行指令时并不会立刻用JIT进行编译。只有部分指令需要JIT进行编译,JIT将决定那些代码将被编译。延迟编译有…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

整理了下luajit 相关内容,分为了几部分,每部分最后是参考的blog地址。有兴趣的可以详细阅读原文。
一、JIT即时编译器
JIT:即时编译器。将频繁执行的代码,通过JIT编译器编译成机器码缓存起来,下次再调用时直接执行机器码。相比与原生Lua的逐条执行虚拟机指令效率更高。对于那些只执行一次的代码,则保持于原生Lua一样,逐条执行。JIT带来的效率提升,并不一定能抵消编译效率的下降。
当虚拟机执行指令时并不会立刻用JIT进行编译。只有部分指令需要JIT进行编译,JIT将决定那些代码将被编译。延迟编译有助于JIT选择一个最优的解决方案,进行决策。

二、Luajit性能优化
1.使用ffi实现数据结构,减少内存消耗,避免hash重构。
2.用ffi调用C函数,ffi中会声明函数原型包含参数返回值的类型,jit可以直接生成机器码,从而实现对c函数调用的无缝对接,消除了对Lua虚拟堆栈的操作。

三、Luajit 和Lua区别:
hash算法不一样,导致表的遍历顺序不同。
Luajit中新增了一些转义字符,并且处理转义字符的方式也不一样。
Luajit内存上线是4G
函数中的局部变量最大限制Luajit要小于Lua
Luajit不够稳定,在ios上不支持JIT功能

四、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 = CType(10)

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 = function(a, b) return point(a.x+b.x, a.y+b.y) end,
__len = function(a) return math.sqrt(a.x*a.x + a.y*a.y) end,
__index = {
area = function(a) 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 = point(3, 4)
print(a.x, a.y) –> 3 4
print(#a) –> 5
print(a:area()) –> 25
local b = a + point(0.5, 8)
print(#b) –> 12.5

4.cdata = ffi.gc(cdata, finalizer):为 cdata设置析构函数,当cdata不在被其他对象引用时触发。

5.ffi.sizeof:返回Cdata内存大小
print( ffi.sizeof(“int[?]”,10) ) –> sizeof(int) * 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.string(ptr [,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.string(CStr) — ctype<const char*> 转 lua string
print(LuaStr) –> abc

五、ffi基本用法:
(1)、调用C函数(提高函数执行效率)
1.C标准库中函数
local ffi = require(“ffi”)ffi.cdef[[
int printf(const char *fmt, …);
]]ffi.C.printf(“Hello %s!”, “world”)
首先 require(“ffi”) 加载ffi库,然后声明函数,最后表用函数

2.调用其他库函数
在调用函数前先 ffi.load(库名,[])加载库,C标准库是默认加载的不需要手动load。
3.调用C/C++自定义函数
在C/C++中声明函数时 添加 extern “C” __declspec(dllexport)修饰函数。

ffi只可在lua中调用C/C++中的导出函数,也就是库函数或extern “C” __declspec(dllexport)修饰的自定义函数。

(2)、在Lua中使用C结构体(减少内存开销)
ffi.cdef [[
typedef struct MyStruct{char a; char b;} Point;
]]
local point = ffi.new(“Point”)
print(ffi.sizeof(point))
定义结构体,并不需要要在C/C++中定义,只需在Lua中定义即可。构造一个对象。print(ffi.sizeof(point)) = 2 point占用两个字节。

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








版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/184998.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • JAVA 二分法

    JAVA 二分法JAVA 二分法

    2022年4月23日
    41
  • FFplay硬件加速[通俗易懂]

    FFplay硬件加速[通俗易懂]本文以ffmpeg-4.4源码为准,a.mp4下载链接:百度网盘,提取码:nl0s。FFplay硬件解码命令如下:ffplay.exe-vcodech264_cuvid-ia.mp4上面命令指定了NVIDIA的硬件解码器,h264_cuvid。在ffplay.c的代码里面硬件解码跟普通解码在逻辑上没有做什么特殊的处理。ffplay.c里面没有像ffmpeg.c那样支持-hwaccel这个选项,所以ffplay.c的硬件解码流程跟普通解码…

    2022年6月25日
    56
  • 关于软件定义网络SDN(服务器虚拟化的定义)

    1、SDN软件定义网络在传统的网络中,各个转发节点(路由器、交换机)都是独立工作的,内部管理命令和接口也是厂商私有的,不对外开放。而SDN(SoftwareDefinedNetworking)网络,就是在网络上建立了一个SDN控制器节点,统一管理和控制下层设备的数据转发,可以理解为软件定义的网络或者软件控制的网络。下级节点的管理功能被剥离给了SDN控制器,只剩下转发功能。SDN,SoftwareDefinedNetworking,即软件定义网络。或者也可以理解为,软件定义的网络、软件控制的网络、

    2022年4月18日
    45
  • VMware虚拟机中安装Linux系统详细步骤(方法一)「建议收藏」

    VMware虚拟机中安装Linux系统详细步骤(方法一)「建议收藏」linux系统下载地址:linux镜像文件下载地址:登录Centos官网下载或进入链接:https://pan.baidu.com/s/19j5hrW2U754SPH9p2H6E0Q提取码:krzl百度网盘进行下载安装步骤打开VMware虚拟机点击创建虚拟机点击自定义,再点击下一步硬件兼容性默认,直接单击下一步点击浏览,在目录下找到自己下载的linux系统的镜像文件,选择后…

    2025年11月2日
    6
  • 使用Java代码过滤掉乱码字符

    使用Java代码过滤掉乱码字符转自:http://www.cnblogs.com/en-heng/p/5320024.html最近在日志数据清洗时遇到中文乱码,如果只要有非中文字符就将该字符串过滤掉,这种方法虽简单但并不可取,因为比如像Xperia™主題、天天四川麻将Ⅱ这样的字符串也会被过滤掉。1.Unicode编码Unicode编码是一种涵盖了世界上所有语言、标点等字符的编码方式,简单一点说

    2022年6月11日
    94
  • 只读挂载磁盘linux,linux挂载磁盘就变只读怎么解决

    只读挂载磁盘linux,linux挂载磁盘就变只读怎么解决Linux系统挂载存储变成只读的解决方案:1、mount:用于查看哪个模块输入只读,一般显示为:[root@localhost~]#mount/dev/cciss/c0d0p2on/typeext3(rw)procon/proctypeproc(rw)sysfson/systypesysfs(rw)devptson/dev/ptstypedevpts(r…

    2022年6月19日
    24

发表回复

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

关注全栈程序员社区公众号