当前位置: 首页 > news >正文

基于ToLua的C#和Lua内存共享方案保姆级教程

C#和Lua内存共享方案保姆级教程

前言

在介绍C#和Lua内存共享方案之前,先介绍下面两个点来支撑这个方案的必要性

跨语言交互很费

Lua和C#交互最早是基于反射的方式实现的,后来为了提升性能发展成Luajit+C#静态方法导出注入到lua虚拟机的方式至此Lua+Unity的性能才达到了实用的级别,但我们如果用的不好还是会存在诸多性能问题,具体的一些使用注意事项参考引用里《用好lua+unity,让性能飞起来——lua与c#交互篇》,用文章中的一个例子来加深一下我们lua点点调用一个对象的属性的写法在Lua+C#的组合模式下是有多么的费劲能,虽然写起来很轻松,但实际交互都是调用的虚拟栈,会经历压栈,出栈等操作,性能会随着调用次数的频繁和参数传递的越多而变的越差,看了下面的交互步骤之后就意识到尽可能的避免这种点属性的链式写法

game.bject.transorm.position = pos写法在项目中很常见,但大量使用就比较糟糕,因为每点一次属性就意味着要经过堆栈调用,有的甚至还要经过Dictionary容器查询操作,内部又是好几条指令,每一次指令就意味着时间开销,尽管一次很小但调用次数多了之后就可观了,要实现这个坐标赋值的操作,lua堆栈调用如下
第一步

  GameObjectWrap.get_transform        lua想从gameobj拿到transform,对应gameobj.transformLuaDLL.luanet_rawnetobj             把lua中的gameobj变成c#可以辨认的idObjectTranslator.TryGetValue        用这个id,从ObjectTranslator中获取c#的gameobject对象gameobject.transform                准备这么多,这里终于真正执行c#获取gameobject.transform了ObjectTranslator.AddObject          给transform分配一个id,这个id会在lua中用来代表这个transform,transform要保存到ObjectTranslator供未来查找LuaDLL.luanet_newudata              在lua分配一个userdata,把id存进去,用来表示即将返回给lua的transformLuaDLL.lua_setmetatable             给这个userdata附上metatable,让你可以transform.position这样使用它LuaDLL.lua_pushvalue                返回transform,后面做些收尾LuaDLL.lua_rawsetiLuaDLL.lua_remove

第二步:

  TransformWrap.set_position                      lua想把pos设置到transform.positionLuaDLL.luanet_rawnetobj                         把lua中的transform变成c#可以辨认的idObjectTranslator.TryGetValue                    用这个id,从ObjectTranslator中获取c#的transform对象LuaDLL.tolua_getfloat3                          从lua中拿到Vector3的3个float值返回给c#lua_getfield + lua_tonumber 3次                 拿xyz的值,退栈lua_pop

transform.position = new Vector3(x,y,z) 准备了这么多,终于执行transform.position = pos赋值了
上面的内部堆栈调用说明了lua点属性或者方法调用比较费性能,语言交互代价比较"昂贵"

我们在用unity profiler的时候也会发现有的调用比较深的堆栈一页都拉不到底,当然可能是存在递归调用的情况,这调用嵌套越,执行花费的时间就越多,而上面的gameobject.transform每次如果临时使用很快就会被lua gc掉,下次再调用又会重新走一遍这个堆栈调用的流程就会很费性能

参数传递也很费

用传统的虚拟栈传递参数的方式同样的道理,尤其是Unity特有的值类型结构(Vector3,Quaternion等),lua中一个Vector3就是一个table,跟C#是Vector3是两种结构,就会涉及到这两种类型的转换,例如将C# Vector3传递给Lua,流程如下:

  1. C#中拿到Vector3的x、y、z三个值;
  2. Push这3个float给Lua栈;
  3. 然后构造一个表,将表的x,y,z赋值;
  4. 将这个表push到返回值里。
    一个传vector的操作会经历三次push参数、表内存分配、和3次表插入等操作,虽然单次指令也就那么大几个,但这种频繁操作的代码会导致性能下降
目前项目中参数传递的两种方式
第一种、SendMessage的方式

通过Lua虚拟栈采用数据压栈和出栈的方式(获取对应的LuaTable的方法,传参的方式)
在这里插入图片描述
在这里插入图片描述

第二种、C#持有LuaTable

C#通过LuaState获取到对应的table,然后给这个table添加对应的数据,也可以添加上table,这种方式有明显的利弊,可读性差,如果采用哈希的结构会有key字符串的内存开销,针对复杂的嵌套类型写起来极其"恶心",下不了手,适合简单的类型还是可以考虑的
在这里插入图片描述

上面两种方式的性能对比

天之之前测试血条、蓝条将SendMessage的方式改成LuaTable共享的方式做的对比测试

  • SendMessage Call Function的方式
    在这里插入图片描述

  • LuaTable共享的方式
    在这里插入图片描述

由上面的图可见LuaTable的方式还是比方法调用的方式传参性能要好很多,但看他们性能图还是会稳定的性能尖峰,尽管是峰值从42ms降低到10ms,但稳定的10ms尖峰还是需要

相关文章:

基于ToLua的C#和Lua内存共享方案保姆级教程

C#和Lua内存共享方案保姆级教程 前言 在介绍C#和Lua内存共享方案之前,先介绍下面两个点来支撑这个方案的必要性 跨语言交互很费 Lua和C#交互最早是基于反射的方式实现的,后来为了提升性能发展成Luajit+C#静态方法导出注入到lua虚拟机的方式至此Lua+Unity的性能才达到了实…...

OpenCV与AI深度学习|16个含源码和数据集的计算机视觉实战项目(建议收藏!)

本文来源公众号“OpenCV与AI深度学习”,仅用于学术分享,侵权删,干货满满。 原文链接:分享|16个含源码和数据集的计算机视觉实战项目 本文将分享16个含源码和数据集的计算机视觉实战项目。具体包括: 1. 人…...

Vue 如何简单更快的对 TypeScript 中接口的理解?应用场景?

TypeScript 中接口(Interface)的理解与应用 在 TypeScript 中,接口(Interface) 是一种用来定义对象的结构或形状的方式。接口可以指定对象中应该包含哪些属性、这些属性的类型以及它们的函数签名。接口帮助我们在代码…...

R语言绘图过程中遇到图例的图块中出现字符“a“的解决方法

R语言绘图过程中遇到图例的图块中出现字符的解决方法 因为我遇到这个问题的时候没在网上找到合适的方法,找到个需要付费的,算了。也许是因为问的方式不同,问了半天AI也回答出来,莫名有些烦躁,打算对代码做个分析&…...

视图合并机制解析 | OceanBase查询优化

背景 在默认配置下,若查询语句中嵌入了视图,系统会先等待视图内部所包含的查询完全执行完成后,再继续执行父查询。这种方式造成优化器无法将视图查询与外层查询视为一个整体来进行优化处理,从而限制了优化效果。因此,…...

sql注入报错分享(mssql+mysql)

mysql mysql的报错内容比较多 网上也有比较多的 这里重复的就不多介绍了。一笔带过 溢出类 bigint 当超过mysql的整形的时候,就会导致溢出,mysql可能会将错误信息带出。这里user()是字母默认为0 取反以后1可能就会导致异常。 报错特征 BIGINT UNSIG…...

PHP 高并发解决方案

PHP作为一种脚本语言,在处理高并发请求时可能面临一些挑战。但通过合理的设计和优化,可以有效提升PHP应用程序的性能和并发处理的能力。 一、缓存 页面缓存:将生成的页面缓存起来,减少对数据库的查询,提高响应速度。…...

k8s1.30.0高可用集群部署

负载均衡 nginx负载均衡 两台nginx负载均衡 vim /etc/nginx/nginx.conf stream {upstream kube-apiserver {server 192.168.0.11:6443 max_fails3 fail_timeout30s;#server 192.168.0.12:6443 max_fails3 fail_timeout30s;#server 192.168.0.13:6443 max_fails3…...

多摩川编码器协议及单片机使用

参考: https://blog.csdn.net/qq_28149763/article/details/132718177 https://mp.weixin.qq.com/s/H4XoR1LZSMH6AxsjZuOw6g 1、多摩川编码器协议 多摩川数据通讯是基于485 硬件接口标准NRZ 协议,通讯波特率为2.5Mbps 的串行通讯,采用差分两…...

Android 网络通信(三)OkHttp实现登入

学习笔记 目录 一. 先写XML布局 二、创建 LoginResponse 类 :封装响应数据 目的和作用: 三、创建 MyOkHttp 类 :发送异步请求 代码分析 可能改进的地方 总结 四、LoginActivity 类中实现登录功能 详细分析与注释: 总结: 改进建议: 零、响应数据样例 通过 P…...

分享一下arr的意义(c基础)(必看)(牢记)

arr 即数组名 一般指数组首元素地址 在两种情况下不是 1:sizeof(arr) arr指整个数组简单讲解一下strlen与sizeof(c基础)_strzeof在c语言中什么意思-CSDN博客 2:printf("%p",&…...

AGENT AI 综述核心速览

研究背景 研究问题:这篇文章探讨了多模态人工智能(Agent AI)系统在理解和响应视觉和语言输入方面的潜力,特别是在物理和虚拟环境中的应用。Agent AI旨在通过感知和行动来增强人工智能系统的交互性和适应性。研究难点:…...

基于Java Springboot房屋租赁系统

一、作品包含 源码数据库设计文档万字PPT全套环境和工具资源部署教程 二、项目技术 前端技术:Html、Css、Js、Vue、Element-ui 数据库:MySQL 后端技术:Java、Spring Boot、MyBatis 三、运行环境 开发工具:IDEA/eclipse 数据…...

力扣 LeetCode 701. 二叉搜索树中的插入操作(Day10:二叉树)

解题思路&#xff1a; 全部插入到叶子节点即可 class Solution {public TreeNode insertIntoBST(TreeNode root, int val) {if (root null) {TreeNode node new TreeNode(val);return node;}if (root.val < val) {root.right insertIntoBST(root.right, val);}if (root…...

猎板科技:PCB 特殊定制领域的卓越引领者

一、专业团队&#xff0c;创新设计之源 猎板科技的核心竞争力首先源于其卓越的专业团队。这支队伍汇聚了经验丰富的资深工程师以及行业前沿的技术专家&#xff0c;他们在 PCB 设计领域拥有深厚的造诣和敏锐的洞察力。无论是面对常规 PCB 设计任务&#xff0c;还是应对极具挑战…...

centos stream 9安装docker教程

第一步&#xff1a;安装该dnf-plugins-core软件包&#xff08;它提供了管理 DNF 存储库的命令&#xff09; sudo dnf -y install dnf-plugins-core 第二步&#xff1a;设置存储库(这里使用的是阿里云的镜像源) sudo dnf config-manager --add-repo https://mirrors.aliyun.c…...

优化旧LabVIEW程序功能的方法

优化运行已久的LabVIEW程序时&#xff0c;需在不影响原有功能的基础上针对目标功能进行改进。以下结合一个数据采集功能优化的实例&#xff0c;详细说明操作步骤和注意事项&#xff0c;为工程师提供切实可行的方法。 优化背景 某企业的LabVIEW程序负责多通道数据采集&#xf…...

关于安卓模拟器或手机设置了BurpSuite代理和安装证书后仍然抓取不到APP数据包的解决办法

免责申明 本文仅是用于学习研究安卓系统设置代理后抓取不到App数据包实验,请勿用在非法途径上,若将其用于非法目的,所造成的一切后果由您自行承担,产生的一切风险和后果与笔者无关;本文开始前请认真详细学习《‌中华人民共和国网络安全法》【学法时习之丨网络安全在身边一…...

【电路笔记】-布尔逻辑AND函数

逻辑AND函数 文章目录 逻辑AND函数1、概述2、逻辑 AND 函数 仅当所有输入均为 true 时&#xff0c;逻辑与函数输出才为 true&#xff0c;否则输出为 false。 1、概述 布尔代数基于逻辑函数&#xff0c;其中每个布尔函数&#xff08;例如逻辑 AND 函数&#xff09;通常具有一个…...

C#(11) 运算符重载

前言 我们知道函数是可以重载的&#xff0c;重载后的作用是干嘛呢&#xff1f;其实就是为了方便适应不同的参数传递。 那运算符我们也可以理解是一个函数&#xff0c;只是我们希望为更多的参数引入运算符使得他们可以被计算。 c#设计这么一块功能&#xff0c;其实也是为了方…...

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…...

Go 语言接口详解

Go 语言接口详解 核心概念 接口定义 在 Go 语言中&#xff0c;接口是一种抽象类型&#xff0c;它定义了一组方法的集合&#xff1a; // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的&#xff1a; // 矩形结构体…...

2.Vue编写一个app

1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析

Java求职者面试指南&#xff1a;Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问&#xff08;基础概念问题&#xff09; 1. 请解释Spring框架的核心容器是什么&#xff1f;它在Spring中起到什么作用&#xff1f; Spring框架的核心容器是IoC容器&#…...

Mysql中select查询语句的执行过程

目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析&#xff08;Parser&#xff09; 2.4、执行sql 1. 预处理&#xff08;Preprocessor&#xff09; 2. 查询优化器&#xff08;Optimizer&#xff09; 3. 执行器…...

基于 TAPD 进行项目管理

起因 自己写了个小工具&#xff0c;仓库用的Github。之前在用markdown进行需求管理&#xff0c;现在随着功能的增加&#xff0c;感觉有点难以管理了&#xff0c;所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD&#xff0c;需要提供一个企业名新建一个项目&#…...