惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

IT之家
IT之家
A
About on SuperTechFans
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
N
Netflix TechBlog - Medium
Microsoft Security Blog
Microsoft Security Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 三生石上(FineUI控件)
博客园 - 聂微东
博客园 - Franky
D
Docker
Martin Fowler
Martin Fowler
Engineering at Meta
Engineering at Meta
The Cloudflare Blog
人人都是产品经理
人人都是产品经理
Last Week in AI
Last Week in AI
U
Unit 42
F
Fortinet All Blogs
H
Help Net Security
Blog — PlanetScale
Blog — PlanetScale
Microsoft Azure Blog
Microsoft Azure Blog
罗磊的独立博客
P
Proofpoint News Feed
月光博客
月光博客
G
Google Developers Blog

博客园 - simonw

IIS7权限简述 MoinMoin Wiki 1.7优化与维护经验 - simonw WoW安全模板技术文档翻译 - SecureStateHeader 雕虫小技之MoinMoin Wiki与Discuz论坛的单点登陆整合 雕虫小技之为Discuz论坛添加Wiki语法 - simonw - 博客园 MoinMoin Wiki 在Linux Apache下的安装 Wiki你长的为何与众不同--对Wiki独创写作语法原因的思考 MoinMoin Wiki 在IIS下的安装与升级 Metatable In Lua 浅尝辄止 Lua中实现类似C#的事件机制 MoinMoin Wiki 权限使用指南 MoinMoin Wiki 引擎概览 Wiki服务商简介 N-Layer, COP, SOA In WOW Addon Develop Ioc容器应用浅析 WOW插件:ShortStory 1.3 发布(2007.7.5) Castle ActiveRecord 泛型应用 WOW插件:ShortRobot 1.21 发布(2006.10.3) WOW插件:ShortUnitFrame 2.1 发布(2007.7.17)
Lua5.1中可变参数...对性能的影响 - simonw - 博客园
simonw · 2010-01-28 · via 博客园 - simonw

在Lua开发中我们会用到"..."这样的语法以表示不确定参数的输入及返回. 但一些用法可能导致性能上的问题你大约从来没有注意过, 它却在不知不觉中对程序的性能产生着潜移默化的影响.

首先来看例子会很直接, 这个例子展示了在不同的"..."的使用方式下, 执行10000次是对内存产生的影响. Lua 5.1环境.

collectgarbage("stop")
print("init memory:"..collectgarbage("count"))function test(...)
    
return 1 + select(1, ...) --A result memory:22.2587890625

    
--select(1,...);return 1 --B result memory:22.2587890625

    
--return 1, ... --C result memory:22.0947265625

    
--return 1 + arg[1] --D result memory:803.3623046875

    
--return 1 --E result memory:803.3544921875

    
--return 1 + 1 --F result memory:803.3544921875

    
--return 1, unpack(arg) --G result memory:803.5185546875

    
--return 1, arg[1], ... --H error attempt to index local 'arg' (a nil value)

    
--return 1 + #{...} --I result memory:490.9072265625
    
    
--select(1,...);return 1,{1} --J result memory:491.0712890625
endprint("start memory:"..collectgarbage("count"))
for i = 110000 do
    test(i)
end
print("result memory:"..collectgarbage("count"))

 第一步要把GC关掉, 以免中途引发垃圾回收影响我们对内存大小的观察. test方法中的每一行都是一种情况, 运行时请将其他行注释掉, 保持一行在执行, 每行后面的注释result momery则是在当前用法下内存大小的结果.

从上面例子的结果中, 我们看到了在对"..."应用不同的使用方式时内存变化的情况, 同样的东西, 内存占用却是从20多到800多的巨大差异, 在偶尔几次的调用中这个差异是微不足道的, 一旦被大量重复调用, 缺陷立刻被放大化, 有的方式会频繁的将"..."的内容创建为一个临时表, 在函数结束后stack上的值类型参数内容将被清空, 创建的临时表却留在了heap中, 大量临时表的出现将可能引起频繁的垃圾回收导致影响性能, 这就是应该注意的地方. 同时也看到了一些有趣的现象.

  1. 调用语句E和F, 这里没有使用"..."中的参数, 它却创建了临时表.
  2. 调用语句B, 随便应用下"...", 哪怕不真正的用它, 也不会创建临时表.
  3. 调用语句H, 一旦应用了"...", arg的临时表变量就不会被创建. 至此看出些端倪了吧, 应证了上两个现象的结果.
  4. 调用语句I, 可以看出arg临时表的内存消耗竟然快是自建表的近2倍.

知道这些规律了, 对写程序应该是很有帮助的, 可能你还在发愁为何gc会被频繁调用, 问题就在这里了.

更多讨论参见CWDG论坛: http://bbs.cwowaddon.com/thread-6700-1-1.html