Lua优化技巧
常见的Lua优化小技巧
- Lua常见优化点:
- 1. 尽量使用局部变量
- 2. table的相关
- 减少对表的访问
- for循环
- 预分配表空间
- 元表
- 3. string的相关
- 4. 避免运行时加载编译
- 5. 尽量避免频繁创建临时对象
- 闭包
- 表
Lua常见优化点:
1. 尽量使用局部变量
尽量将变量局部化,尤其是频繁使用的变量,是Lua最重要的优化方式
-- 使用全局变量
function sumGlobal(n)local sum = 0for i = 1, n dosum = sum + GLOBAL_VALUEendreturn sum
end-- 使用局部变量
function sumLocal(n)local sum = 0local local_value = GLOBAL_VALUEfor i = 1, n dosum = sum + local_valueendreturn sum
endGLOBAL_VALUE = 1local n = 1000000
local start_time = os.clock()
sumGlobal(n)
print("sumGlobal:", os.clock() - start_time)start_time = os.clock()
sumLocal(n)
print("sumLocal:", os.clock() - start_time)-- sumGlobal: 0.020
-- sumLocal: 0.010
2. table的相关
减少对表的访问
表访问也有一定的开销,可以将常用的表元素存储在局部变量中
local t = {x = 1, y = 2, z = 3}-- 直接访问表
function accessTableDirectly(n)local sum = 0for i = 1, n dosum = sum + t.x + t.y + t.zendreturn sum
end-- 缓存表元素
function accessTableLocally(n)local sum = 0local x, y, z = t.x, t.y, t.zfor i = 1, n dosum = sum + x + y + zendreturn sum
endn = 1000000
start_time = os.clock()
accessTableDirectly(n)
print("accessTableDirectly:", os.clock() - start_time)start_time = os.clock()
accessTableLocally(n)
print("accessTableLocally:", os.clock() - start_time)-- accessTableDirectly: 0.030
-- accessTableLocally: 0.015
for循环
数值 for 循环在 Lua 中比泛型 for 循环更快
local t = {}
for i = 1, 1000000 dot[i] = i
end-- 泛型 for 循环
function genericForLoop(n)local sum = 0for _, v in ipairs(t) dosum = sum + vendreturn sum
end-- 数值 for 循环
function numericForLoop(n)local sum = 0for i = 1, n dosum = sum + t[i]endreturn sum
endn = 1000000
start_time = os.clock()
genericForLoop(n)
print("genericForLoop:", os.clock() - start_time)start_time = os.clock()
numericForLoop(n)
print("numericForLoop:", os.clock() - start_time)-- genericForLoop: 0.060
-- numericForLoop: 0.030
预分配表空间
在创建大型表时,预先分配表的大小可以提高性能
-- 动态增加表大小
function dynamicTable(n)local t = {}for i = 1, n dot[i] = iendreturn t
end-- 预分配表大小
function preallocatedTable(n)local t = {}for i = 1, n dot[i] = iendreturn t
endn = 1000000
start_time = os.clock()
dynamicTable(n)
print("dynamicTable:", os.clock() - start_time)start_time = os.clock()
preallocatedTable(n)
print("preallocatedTable:", os.clock() - start_time)-- dynamicTable: 0.050
-- preallocatedTable: 0.040
元表
- 频繁设置元表:
每次对象创建时都设置元表,导致大量内存分配和元表初始化操作。
因为每次都重新设置元表,导致性能开销最大。- 预定义元表:
预先定义好元表,并在对象创建时一次性设置,减少了频繁设置元表的开销。
相比频繁设置元表,性能显著提升。- 缓存元方法:
通过将元方法缓存到局部变量中,避免了每次访问属性时的元表查找。
进一步减少了运行时的查找和调用开销,性能最佳。
-- 频繁设置元表
local start_time = os.clock()
local function createObject()local obj = {}setmetatable(obj, {__index = function(t, k)return "value"end,__newindex = function(t, k, v)rawset(t, k, v)end,})return obj
endfor i = 1, 1000000 dolocal obj = createObject()local value = obj.some_key
endprint("Time taken with frequent setmetatable:", os.clock() - start_time)
---------------------------------------------------------------------------- 预定义元表
local start_time = os.clock()
local mt = {__index = function(t, k)return "value"end,__newindex = function(t, k, v)rawset(t, k, v)end,
}local function createObject()local obj = {}setmetatable(obj, mt)return obj
endfor i = 1, 1000000 dolocal obj = createObject()local value = obj.some_key
endprint("Time taken with predefined metatable:", os.clock() - start_time)
---------------------------------------------------------------------------- 缓存元方法
local start_time = os.clock()local mt = {__index = function(t, k)return "value"end,__newindex = function(t, k, v)rawset(t, k, v)end,
}local obj = setmetatable({}, mt)
local __index = mt.__index
for i = 1, 1000000 dolocal value = __index(obj, "some_key")
endprint("Time taken with cached metatable method:", os.clock() - start_time)-- Time taken with frequent setmetatable: 1.5 seconds
-- Time taken with predefined metatable: 0.3 seconds
-- Time taken with cached metatable method: 0.1 seconds
3. string的相关
- 对于少量字符串连接,… 操作符非常方便。然而,当需要连接大量字符串时,使用 … 操作符的性能会显著下降。因为每次使用 … 操作符都会创建一个新的字符串,涉及大量的内存分配和数据复制操作。
- table.concat 函数用于连接表中的字符串,性能优于 … 操作符,特别是在连接大量字符串时。
-- 使用字符串连接操作符
-- 每次循环迭代都会创建一个新的字符串,并将结果赋值给 result。
-- 由于每次都要分配新的内存并复制已有的字符串内容,导致性能开销较大。
function concatOperator(n)local str = ""for i = 1, n dostr = str .. iendreturn str
end-- 使用 table.concat
-- 将所有字符串存储在一个表中,然后使用 table.concat 一次性连接所有字符串。
-- 这种方式只需要一次内存分配和数据复制操作,性能开销较小。
function concatTable(n)local t = {}for i = 1, n dot[#t + 1] = iendreturn table.concat(t)
endn = 10000
start_time = os.clock()
concatOperator(n)
print("concatOperator:", os.clock() - start_time)start_time = os.clock()
concatTable(n)
print("concatTable:", os.clock() - start_time)-- concatOperator: 2.500
-- concatTable: 0.050
4. 避免运行时加载编译
尽量避免在运行时动态加载和编译代码。例如,避免频繁使用 loadstring 或 load 函数来动态创建和执行 Lua 代码。
local start_time = os.clock()
for i = 1, 1000000 dolocal code = "return " .. ilocal func = load(code)func()
end
print("Runtime compilation:", os.clock() - start_time)local start_time = os.clock()
for i = 1, 1000000 dolocal func = function() return i endfunc()
end
print("Avoid runtime compilation:", os.clock() - start_time)-- Runtime compilation: 10.0
-- Avoid runtime compilation: 0.5
5. 尽量避免频繁创建临时对象
闭包
频繁创建闭包会带来性能开销,因为每次创建闭包都需要分配内存并捕获外部变量。通过避免在循环中创建不必要的闭包,可以提高性能。
local start_time = os.clock()local function createClosures1()local closures = {}for i = 1, 1000000 doclosures[i] = function() return i endendreturn closures
endlocal closures = createClosures1()print("Frequency of closure creation:", os.clock() - start_time)-- Validate closures
for i = 1, 10 doprint(closures[i]()) -- Should print 1, 2, ..., 10
end------------------------------------------------------------------------------------local start_time = os.clock()local function createClosures2()local closures = {}local function createClosure2(i)return function() return i endendfor i = 1, 1000000 doclosures[i] = createClosure2(i)endreturn closures
endlocal closures = createClosures2()print("Avoid frequency of closure creation:", os.clock() - start_time)-- Validate closures
for i = 1, 10 doprint(closures[i]()) -- Should print 1, 2, ..., 10
end-- Frequency of closure creation: 1.5
-- Avoid frequency of closure creation: 0.3
表
频繁创建表会导致性能下降,因为每次创建表都需要分配内存和初始化表结构。通过重用表或预先分配表可以提高性能。
local start_time = os.clock()
local function createTables1()local tables = {}for i = 1, 1000000 dotables[i] = {x = i, y = i * 2}endreturn tables
endlocal tables = createTables1()
print("Frequency of table creation:", os.clock() - start_time)
---------------------------------------------------------------------
local start_time = os.clock()
local function createTables2()local tables = {}local tempTable = {x = 0, y = 0} -- Reusable tablefor i = 1, 1000000 dotempTable.x = itempTable.y = i * 2tables[i] = {x = tempTable.x, y = tempTable.y} -- Copy values to new tableendreturn tables
endlocal tables = createTables2()
print("Avoid frequency of table creation:", os.clock() - start_time)
---------------------------------------------------------------------
local start_time = os.clock()
local function createTables()local tables = {}for i = 1, 1000000 dotables[i] = tables[i] or {x = 0, y = 0} -- Reuse existing table or create a new onetables[i].x = itables[i].y = i * 2endreturn tables
endlocal tables = createTables()
print("Further optimized table creation:", os.clock() - start_time)-- Frequency of table creation: 2.0
-- Avoid frequency of table creation: 1.2
-- Further optimized table creation: 0.8
相关文章:
Lua优化技巧
常见的Lua优化小技巧 Lua常见优化点:1. 尽量使用局部变量2. table的相关减少对表的访问for循环预分配表空间元表 3. string的相关4. 避免运行时加载编译5. 尽量避免频繁创建临时对象闭包表 Lua常见优化点: 1. 尽量使用局部变量 尽量将变量局部化&#x…...
探索CSS中的cursor鼠标属性
在网页设计中,细节决定成败。CSS的cursor属性是这些细节中的关键一环,它不仅影响着网页的美观,更关乎用户体验。今天,我们就来深入了解一下cursor属性,看看如何通过它来增强网页的交互性。 cursor属性概览 cursor属性…...
图象去噪1-使用中值滤波与均值滤波
1、中值滤波 使用中值滤波去除图像的异常像素点,使用cv2.cv2.medianBlur(img, 3)表示再图像在中值滤波窗口3*3的范围内,从下到大排序,将当前值替换为排序中值(如下图所示)将56替换为(56,66,90,…...
微软Edge浏览器全解析
微软Edge浏览器是一款由微软开发的现代网页浏览器,旨在为用户提供高效、安全和可定制的浏览体验。 这款浏览器最初于2015年发布,作为Internet Explorer(IE)的继任者,并随着Windows 10操作系统一同亮相。然而࿰…...
Windows操作系统安装mysql数据库(zip安装包)
MySQL是目前最为流行的开放源码的数据库,是完全网络化的跨平台的关系型数据库系统,它是由瑞典MySQLAB公司开发,目前属于Oracle公司。任何人都能从Internet下载MySQL软件,而无需支付任费用,并且“开放源码”意味着任何人…...
什么是仓颉编程语言?
仓颉编程语言是一款面向全场景智能的新一代编程语言,主打原生智能化、天生全场景、高性能和强安全。 以下是仓颉编程语言的相关介绍: 原生智能化:仓颉编程语言内嵌了AgentDSL的编程框架,将自然语言与编程语言进行了有机融合&…...
ONLYOFFICE8.1-------宝藏级别桌面编辑器测评
简介 ONLYOFFICE 8.1 是一个功能强大的办公套件,提供了一系列广泛的功能,用于文档管理、协作和沟通。它包括用于创建和编辑文本文档、电子表格、演示文稿等的工具。ONLYOFFICE 8.1 的一些关键特性包括: 1. 协作:ONLYOFFICE 8.1 允…...
微信小程序笔记 七!
页面配置 1. 页面配置文件的作用 小程序中,每个页面都有自己的 .json 配置文件,用来对当前页面的窗口外观、页面效果等进行配置。 2. 页面配置和全局配置的关系 小程序中,app.json 中的 window 节点,可以全局配置小程序中每个…...
GPT-5的即将登场:新一代大语言模型的无限可能
GPT-5的即将登场:新一代大语言模型的无限可能 人工智能领域正经历着一场前所未有的变革,而其中大语言模型的进步尤为瞩目。继GPT-4取得巨大成功后,OpenAI即将推出的GPT-5被寄予厚望。作为新一代大语言模型,GPT-5在各个方面都有望…...
微信小程序的常用事件的用法
在微信小程序中,事件绑定是非常常见的操作。以下是一些常用事件的具体用法和示例: 1. bindtap 或 catchtap 点击事件,当用户点击某个元素时触发。 html <!-- WXML 文件 --> <view bindtap"handleTap">点击我<iew…...
前端 CSS 经典:保持元素宽高比
前言:在很多网站,不管页面宽度的变化,都需要里面的图片或者视频,宽高比不变。有两种实现方式。 1. aspect-ratio 属性 使用 aspect-ratio 属性可以直接定义元素的宽高比,但是有兼容性问题 <!DOCTYPE html> &l…...
MES工业一体机的自动化控制技术
MES工业一体机是一种集成了物料管理、生产计划、设备管理、质量控制等功能于一身的智能化生产设备。其自动化控制技术是指通过计算机自动控制系统,实现对生产过程中各种参数的监测、调整和控制,从而提高生产效率、降低生产成本和提高产品质量的一种技术手…...
三品PDM电子行业解决方案介绍 电子企业PDM应用效果
随着全球化和技术创新的不断推进,电子行业正经历着前所未有的发展机遇。然而,随之而来的挑战也日益凸显,尤其是在产品数据管理PDM方面。本文将探讨电子行业在PDM方面的需求,并提出相应的解决方案,以帮助企业提升效率和…...
模拟面试之外卖点单系统(高频面试题目mark)
今天跟大家分享一个大家简历中常见的项目-《外卖点单系统》,这是一个很经典的项目,有很多可以考察的知识点和技能点,但大多数同学都是学期项目,没有实际落地,对面试问题准备不充分,回答时抓不到重点&#x…...
SwiftUI 6.0(iOS 18/macOS 15)关于颜色 Color 的新玩法
概览 WWDC 2024 重装升级的 SwiftUI 6.0 让 Apple 不同平台(iOS 18/macOS 15)显得愈发的冰壶玉衡、美轮美奂。 之前梦寐以求的颜色混合功能在 WWDC 24 里终于美梦成真啦! 在本篇博文中,您将学到如下内容: 概览1. 梦想…...
C++核心编程运算符的重载
C核心编程运算符的重载 文章目录 C核心编程运算符的重载1.“”运算符的重载1.1 作为成员函数重载1.2 作为全局函数重载 2."<<"运算符重载2.1为什么需要重载左移运算符2.2如何重载左移运算符2.3注意事项 3.""运算符重载3.1 前置递增运算符重载3.2后置…...
雷达标定与解析
融合雷达与解析雷达数据的相关代码。感谢开源社区的贡献。以下代码继承了很多人的工作。 如果是单雷达: 直接进行标定,所以就是接收相关的话题然后发布。 lidar_calibration_params.yaml: calibration:在这个接口里面x_offset: 0.0y_offset:…...
养殖自动化温控系统:现代养殖场的智能守护神
现代农业养殖业中,养殖自动化温控系统已经成为提高生产效率和保障动物福利的关键技术之一。本篇文章将深入介绍养殖自动化温控系统的原理、组成、优势及其在不同类型养殖场中的应用实例,并展望该技术的未来发展。 一、养殖自动化温控系统概述 养殖自动…...
用python打印——九九乘法表2
for i in range(1, 10):for j in range(1, i 1):print(f"{j} * {i} {j * i}\t", end)j 1print()外层的 for 循环从 1 到 9 遍历 i。对于每个 i,内层的 for 循环从 1 到 i 遍历 j。在每次循环中,打印出 j 乘以 i 的结果,并以制表…...
如何系统学习机器学习?
我不是计算机专业,第一次接触机器学习还是在研一的时候,当时是看到机器学习可以做号码识别,就觉得好厉害,想学这个。 首次了解到Python这门语言,知道了机器学习可以做什么后,就感觉打开了新世界一样。再后来…...
AM62A1-Q1汽车视觉处理器:低功耗、高集成度的车载视觉解决方案
1. 项目概述:为什么我们需要一颗“小而美”的汽车视觉处理器?最近在做一个车载环视和DMS(驾驶员监控系统)的预研项目,客户对成本和功耗卡得非常死,但功能要求却一点没降:需要同时处理1到2路摄像…...
Thorium浏览器实战指南:为什么这个Chromium分支能让你告别卡顿与隐私泄露?
Thorium浏览器实战指南:为什么这个Chromium分支能让你告别卡顿与隐私泄露? 【免费下载链接】thorium Chromium fork named after radioactive element No. 90. Source code and Linux releases. Windows/MacOS/ARM builds served in different repos, li…...
try-catch到底有没有性能开销
有一种说法是”try-catch 有性能开销,关键路径上不要用”。另一种说法是”try-catch 不抛异常的话没有开销”。这两种说法都不全对,开销在哪里要看具体用法。try-catch 本身不贵,异常对象才贵JVM 里,try-catch 的实现方式是在字节…...
OpenSTA静态时序分析工具:从入门到精通的完整指南
OpenSTA静态时序分析工具:从入门到精通的完整指南 【免费下载链接】OpenSTA OpenSTA engine 项目地址: https://gitcode.com/gh_mirrors/op/OpenSTA OpenSTA静态时序分析工具是数字集成电路设计中不可或缺的开源时序验证解决方案。作为一款功能强大的门级静态…...
RK3562核心板开发指南:从硬件设计到AI部署的全流程解析
1. 项目概述:从一颗芯片到一套完整的开发资源最近在嵌入式圈子里,RK3562这颗芯片的热度持续攀升。作为瑞芯微面向中高端AIoT和工业应用推出的新一代处理器,它凭借其均衡的CPU/GPU/NPU性能和出色的能效比,吸引了不少开发者的目光。…...
内网边界安全管控:访问权限隔离与入侵阻断方案
内网边界安全管控的核心目标内网边界安全的核心在于实现访问权限的精细化隔离与实时入侵阻断,需结合网络架构设计、技术工具和流程管理三方面协同实施。访问权限隔离方案网络分层与微隔离 采用零信任架构,将内网划分为核心区、业务区、DMZ区等逻辑区域&a…...
如何5分钟配置Zotero PDF翻译插件:新手快速上手教程
如何5分钟配置Zotero PDF翻译插件:新手快速上手教程 【免费下载链接】zotero-pdf-translate Translate PDF, EPub, webpage, metadata, annotations, notes to the target language. Support 20 translate services. 项目地址: https://gitcode.com/gh_mirrors/zo…...
抗IL-3R-α阻断抗体处理的肿瘤来源内皮细胞外泌体(EVs)的抗血管生成效应:对Wnt/β-catenin通路的洞察
引言血管生成,即从已有血管中形成新血管的过程,是肿瘤生长和转移的关键过程。肿瘤微环境中的促血管生成因子在促进这一过程中起着关键作用。在这些因子中,具有促血管生成特性的细胞因子白细胞介素-3(IL-3)由乳腺癌和卵…...
LizzieYzy:围棋AI分析工具的三大突破,让你拥有职业棋手的复盘能力
LizzieYzy:围棋AI分析工具的三大突破,让你拥有职业棋手的复盘能力 【免费下载链接】lizzieyzy LizzieYzy - GUI for Game of Go 项目地址: https://gitcode.com/gh_mirrors/li/lizzieyzy 还记得上次输掉一盘棋后,你花了多少时间复盘寻…...
若依框架菜单管理进阶:从零构建独立详情页面的完整实践
1. 若依框架菜单管理基础与详情页需求分析 第一次接触若依框架的开发者可能会对它的菜单管理系统感到困惑。作为一个基于Spring Boot和Vue.js的前后端分离框架,若依的菜单管理实际上扮演着系统导航和权限控制的双重角色。在标准代码生成器生成的页面中,…...
