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

[Lua实战]整理Lua中忽略的问题

整理Lua中忽略的问题

    • 1.元表metatable和元方法
      • 1.1元方法_index可以设置为table
      • 1.2.元方法_index可以设置为函数
      • 1.3.元方法_index和_newindex实现只读table
      • 1.4.忽略元方法提取值 rawget和rawset
    • 2.Lua强制GC方法
      • 2.1 collectgarbage()
    • 3.协程和线程的区别
      • 3.1协程coroutine.create()是同步执行,不是并行,只是切了一个上下文,然后执行完协程切回
      • 3.2线程 lua只能通过lua_newthread()必须依托C/C++其他系统才可以
    • 4.lua中.和:的区别
    • 5.lua优化痛点
      • 5.1追加array性能:for循环插入table>table.insert>t[#t+1]
      • 5.2table.concat比正常的字符串..拼接性能要好
      • 5.3如果用到unity中的c#对象比如vector3,直接传xyz的性能好于装箱拆箱后的vector3
      • 5.4少用全局变量,多使用全局的表
      • 5.5配表设置默认值
      • 5.6 尽量不要在for循环创建表和闭包
      • 5.7 场景切换时可以主动调用Lua的GC(包括C#的GC回收内存)
      • 5.8 XLua/ToLua/SLua中尽量少直接访问unity的类/对象,包括设置值,把对象拆分为多参数简单类型(string,int,float)

在这里插入图片描述

1.元表metatable和元方法

1.1元方法_index可以设置为table

a = {k = 'va'}
b = {kb = 1,k = 'vb'}
mataTb = { __index=b }
setmetatable(a,mataTb)
print(a.kb,a.k)--输出为 1  va

1.2.元方法_index可以设置为函数

a = {k = 'va'}
mataTb = { __index = function(tableA, key)--将a和键传给该函数
	return 'key:'..key --此处..是拼接两个字符串
end }
setmetatable(a,mataTb)
print(a.kk,a.k)--输出为 key:kk  va

1.3.元方法_index和_newindex实现只读table

b = {k = 'v1'}
function func(tb, key, val)
	print('你不能修改表')
end
a = {}
setmetatable(a, { __index = b , __newindex = func})
a.k1 = 1
print(a.k, a.k1)
--上述输出为
你不能修改表
v1	nil

1.4.忽略元方法提取值 rawget和rawset

简单来说就是不使用元表的元方法 直接获取和设置

local tableA = {}
local tableB = {NUM=100}
local tableC = {}

setmetatable(tableA,{__index = tableB, __newindex = tableC})
print(tableA.NUM)
print(rawget(tableA,"NUM"))

tableA.NAME = "AA"
print(tableA.NAME)
print(tableC.NAME)

rawset(tableA,"NAME","I AM AA")
print(tableA.NAME)

-- 输出结果
100
nil
nil
AA
I AM AA

2.Lua强制GC方法

2.1 collectgarbage()

function table.count(t)
    if type(t) ~= "table" then
        assert(false)
        return
    end

    local n = 0
    for k, _ in pairs(t) do
        n = n + 1
    end
    return n
end

local t = {
    x1 = "hello",
    x2 = "world",
    [1] = "x1111",
}

print(table.count(t))
t.x1 = nil
collectgarbage()
print(table.count(t))

--上述输出为
3
2

3.协程和线程的区别

3.1协程coroutine.create()是同步执行,不是并行,只是切了一个上下文,然后执行完协程切回

local function run(data)
print("co-body", 1, data.a)
print("co-body", 2, data.a)
print("co-body", 3, data.a)
coroutine.yield()
print("co-body", 4, data.a)
print("co-body", 5, data.a)
coroutine.yield()
end

local co = coroutine.create(run)

local data = {a=1}
coroutine.resume(co, data)

for i=1,5 do
print("main", i)
end
coroutine.resume(co, data)

3.2线程 lua只能通过lua_newthread()必须依托C/C++其他系统才可以

4.lua中.和:的区别

.需要传入obj对象 :是可以用self:/self.拿到对应的属性的

5.lua优化痛点

5.1追加array性能:for循环插入table>table.insert>t[#t+1]

5.2table.concat比正常的字符串…拼接性能要好

5.3如果用到unity中的c#对象比如vector3,直接传xyz的性能好于装箱拆箱后的vector3

5.4少用全局变量,多使用全局的表

http://lua-users.org/wiki/OptimisingUsingLocalVariables

local b = GLOBAL
next(table)判断非空
for 性能比 while 好

5.5配表设置默认值

local defaultValues = {
   robotName = "des_3115",
}
 
local ARENA = {
   [1] = { rank = { 1, 1, }, robotGroupId = 5000, },
   [2] = { rank = { 2, 2, }, robotGroupId = 4999, },
   [3] = { rank = { 3, 3, }, robotGroupId = 4998, },
   [4] = { rank = { 4, 4, }, robotGroupId = 4997, },
   [5] = { rank = { 5, 5, }, robotGroupId = 4996, },
   [6] = { rank = { 6, 6, }, robotGroupId = 4995, },
   [7] = { rank = { 7, 7, }, robotGroupId = 4994, },
}
 
do
    local base = {
        __index = defaultValues, --基类,默认值存取
        __newindex = function()
            --禁止写入新的键值
            error("Attempt to modify read-only table")
        end
    }
    for k, v in pairs(ARENA) do
        setmetatable(v, base)
    end
    base.__metatable = false --不让外面获取到元表,防止被无意修改
end
 
return ARENA

5.6 尽量不要在for循环创建表和闭包

local t = {1,2,3,'hi'}
for i=1,n do
    --执行逻辑,但t不更改
    ...
end

5.7 场景切换时可以主动调用Lua的GC(包括C#的GC回收内存)

5.8 XLua/ToLua/SLua中尽量少直接访问unity的类/对象,包括设置值,把对象拆分为多参数简单类型(string,int,float)

相关文章:

  • Spring事件详解,Spring-Event源码详解,一文搞透Spring事件管理
  • 【C语言进阶】柔性数组
  • 2023​史上最全软件测试工程师常见的面试题总结​ 备战金三银四
  • Day12【元宇宙的实践构想01】—— 元宇宙概念和发展历程
  • 《从0开始学大数据》之如何自己开发一个大数据SQL引擎
  • websoket是干么的如何基于websoket实现一个简单的消息通信。
  • nacos 服务发现获取列表源码分析
  • 【MySQL】过年没有回老家,在出租屋里整理了一些思维导图
  • 《流浪地球 2》 Deepfake 小试牛刀,45+ 吴京「被」年轻,变身 21 岁小鲜肉
  • C++工程实践必备技能
  • GitHub访问问题与FastGithub下载及使用(详细篇)
  • <使用Python自定义生成简易二维码>——《Python项目实战》
  • Spring Boot 热部署(热加载)
  • 又一个开源工具搞完了,工作效率直接翻倍
  • 入职-环境安装篇
  • [分享]iOS开发 - 实现UITableView Plain SectionView和table不停留一起滑动
  • 《Javascript数据结构和算法》笔记-「字典和散列表」
  • 【140天】尚学堂高淇Java300集视频精华笔记(86-87)
  • 【附node操作实例】redis简明入门系列—字符串类型
  • AWS实战 - 利用IAM对S3做访问控制
  • Bytom交易说明(账户管理模式)
  • Git初体验
  • iOS筛选菜单、分段选择器、导航栏、悬浮窗、转场动画、启动视频等源码
  • JS函数式编程 数组部分风格 ES6版
  • PHP那些事儿
  • React16时代,该用什么姿势写 React ?
  • react-native 安卓真机环境搭建
  • uni-app项目数字滚动
  • WebSocket使用
  • 阿里研究院入选中国企业智库系统影响力榜
  • 对超线程几个不同角度的解释
  • 每天10道Java面试题,跟我走,offer有!
  • 实现简单的正则表达式引擎
  • 使用 QuickBI 搭建酷炫可视化分析
  • 通过npm或yarn自动生成vue组件
  • 微信小程序开发问题汇总
  • Java性能优化之JVM GC(垃圾回收机制)
  • 阿里云API、SDK和CLI应用实践方案
  • 新海诚画集[秒速5センチメートル:樱花抄·春]
  • #define
  • #define与typedef区别
  • (1)(1.11) SiK Radio v2(一)
  • (13)Latex:基于ΤΕΧ的自动排版系统——写论文必备
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第2节(共同的基类)
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (多级缓存)缓存同步
  • (四)linux文件内容查看
  • (原創) 博客園正式支援VHDL語法著色功能 (SOC) (VHDL)
  • ******IT公司面试题汇总+优秀技术博客汇总
  • .Net IE10 _doPostBack 未定义
  • .NET 中创建支持集合初始化器的类型
  • .Net程序帮助文档制作
  • .Net环境下的缓存技术介绍
  • @autowired注解作用_Spring Boot进阶教程——注解大全(建议收藏!)
  • @JoinTable会自动删除关联表的数据