任何指针?收集链接到Lua ML的帖子将做一个答案(总结这些链接的奖励点在这里。)
更新:我已经将标题文本从“profiling”更改为“optimization”指南,因为这更有意义。
解决方法
Mike最近为LuaJIT创建并发布了一个精彩的轻量级分析器,你可以找到它here。
更新
维基在这个领域获得了更多的页面,特别是this one,它详细介绍了这里没有提到的一些额外的东西,并基于Mike的mailing list post。
LuaJIT最近推出了自己的wiki和mailing list,并且有这样的事情来了很多,更多的宝石关于加快LuaJIT的代码。
现在维基是很瘦的(但总是寻找人来添加),但是,最近添加的一个伟大的页面是a list of NYI functions.NiI函数导致JIT纾困和回退到解释器,所以很明显一个应尽可能避免在热路径上的NYI功能,特别是在循环中。
> FFI Array Performance
> An interesting discussion on GC gotcha’s
> Some more small gotcha’s
只是为了重复进一步向下(因为它只是有用的),-jv是性能调整的最佳工具,它也应该是您第一次停止时进行故障排除。
原始答案
我怀疑你会发现很多这个实际上,主要是因为LJ2仍然是测试版,因此大多数配置文件是完全做,因为没有调试挂钩LJ2特定的东西,如跟踪记录器。
在更好的方面,新的FFI模块允许直接调用高分辨率计时器(或者分析api的类似于VTune / CodeAnalyst),你可以这样分析,但是任何更多需要扩展到LJ2 JIT核心,这应该是太难了,因为代码是明确的和注释。
一个跟踪记录器命令行参数(取自here):
The -jv and -jdump commands are extension modules written in Lua. They
are mainly used for debugging the JIT compiler itself. For a
description of their options and output format,please read the
comment block at the start of their source. They can be found in the
lib directory of the source distribution or installed under the jit
directory. By default this is /usr/local/share/luajit-2.0.0-beta8/jit
on POSIX systems.
这意味着您可以使用来自命令的模块代码形成基于LuaJIT 2的概要分析模块的模块代码
更新
随着对问题的更新,这变得更容易回答。所以让我们从源代码开始,LuaJIT.org:
在手动优化代码之前,它总是一个好主意来检查JIT的优化调优资源:
汇编
从Running页面,我们可以看到所有的选项设置JIT的参数,优化,我们专注于-O选项。马上告诉我们,启用所有优化对性能的影响最小,因此请确保以-O3(现在是默认值)运行,因此这里对我们来说真正价值的唯一选项是JIT和Trace阈值。
这些选项非常特定于您正在编写的代码,因此除了默认值之外没有通用的“最佳设置”,但不用说,如果代码有许多循环,可以尝试循环展开并计算执行时间但如果您正在寻找冷启动性能,则在每次运行之间刷新缓存)。
-jv也有助于避免知道issues/’fallbacks’将导致JIT救助。
网站本身不提供如何写更好或更优化的代码,除了一些小的零件在FFI tutorial:
函数缓存
函数的缓存在Lua中是一个很好的性能提升,但是在LuaJIT中重点不太重要,因为JIT自己完成大部分优化,重要的是要注意FFI C函数的缓存是不好的,所以最好缓存命名空间。
页面中的示例:
坏:
local funca,funcb = ffi.C.funcb,ffi.C.funcb -- Not helpful! local function foo(x,n) for i=1,n do funcb(funca(x,i),1) end end
好:
local C = ffi.C -- Instead use this! local function foo(x,n do C.funcb(C.funca(x,1) end end
FFI性能问题
Status部分详细描述了各种结构&降低代码性能的操作(主要是因为它们没有编译,而是使用VM回退)。
现在我们移动到所有LuaJIT宝石的源代码,Lua mailing list:
> Avoiding C Calls and NYI Lua calls in loops:如果您希望LJ2跟踪器启动并提供有用的反馈,则需要避免跟踪编译器无法访问的NYI(尚未实现)函数或C调用。所以如果你有任何小的C调用可以导入到lua并且在循环中使用,导入它们,在最坏的情况下,它们可能比C编译器实现“慢6%”,最好是更快。
> Use linear arrays over ipairs:根据Mike,pairs / next将总是比其他方法慢(还有一个smal tidbit在那里关于符号缓存的示踪器)。
> Avoid nested loops:每个嵌套级别需要额外传递一次跟踪,并且将稍微优化一些,特别是避免使用较低迭代的内部循环。
> You can use 0-base arrays:Mike在这里说,LuaJIT对于基于0的数组没有性能损失,与标准Lua不同。
> Declare locals in the most inner scope as possible:没有真正的解释为什么,但是IIRC这与SSA活性分析有关。还包含一些有趣的信息,如何避免太多的本地(这打破了活力分析)。
> Avoid lots of tiny loops:这会弄乱展开的启发式并将减慢代码。
小花:
> FFI Tips
>作为beta8,我们有字节码,可以用于通过删除解析步骤来提高冷启动性能。
> Some general guidelines来自Mike的FFI类型
> Reuse metatables尽可能多
>加速Lua -> C -> Lua looping
> LJ2没有Lua的metatable bugs,并且避免代理表,正确缓存它。
>更新到Git HEAD时,尽可能的,它almsot总是包含修复和加速ups。
分析工具可用于正常的Lua,但是,有一个更新的项目,正式兼容LuaJIT(我怀疑它会采取任何LuaJIT的功能,但是),luatrace. Lua wiki还有一个页面上optimization tips正常的Lua,这些需要在LuaJIT下测试它们的有效性(这些优化大多数可能已经在内部执行),然而,LuaJIT仍然使用默认GC,这使得它作为一个区域手动优化增益仍然可以伟大直到迈克添加自定义GC,他提到在这里和那里)。
LuaJIT的源代码包含了一些用于修改JIT内部的设置,然而,这些设置需要大量的测试来调整它们的特定代码,事实上,它可能只是更好地避免他们,特别是对于那些人不熟悉JIT的内部。