Lua性能优化技巧(一):前言

和在所有其他编程语言中一样,在Lua中,我们依然应当遵循下述两条有关程序优化的箴言:

原则1:不要做优化。
原则2:暂时不要做优化(对专家而言)。

这两条原则对于Lua编程来说尤其有意义,Lua正是因其性能而在脚本语言中鹤立鸡群。

当然,我们都知道性能是编程中要考量的一个重要因素,指数级时间复杂度的算法会被认为是棘手的问题,绝非偶然。如果计算结果来得太迟,它就是无用的结果。因此,每一个优秀的程序员都应该时刻平衡在优化代码时所花费的资源和执行代码时所节省的资源。

优秀的程序员对于代码优化要提出的第一个问题是:“这个程序需要被优化吗?”如果(仅当此时)答案是肯定的,第二个问题则是:“在哪里优化?”

要回答这样两个问题,我们需要制定一些标准。在进行有效的性能评定之前,不应该做任何优化工作。有经验的程序员和初学者之前的区别并非在于前者善于指出一个程序的主要性能开销所在,而是前者知道自己不善于做这件事情。

几年前,Noemi Rodriguez和我开发了一个用于Lua的CORBA ORB[2]原型,之后演变为OiL。作为第一个原型,我们的实现的目标是简洁。为防止对额外的C函数库的依赖,这个原型在序列化整数时使用少量四则运算来分离各个字节(转换为以256为底),且不支持浮点值。由于CORBA视字符串为字符序列,我们的ORB最初也将Lua字符串转换为一个字符序列(也就是一个Lua表),并且将其和其他序列等同视之。

当我们完成这个原型之后,我们把它的性能和一个使用C++实现的专业ORB进行对比。由于我们的ORB是使用Lua实现的,预期上我们可以容忍它的速度要慢一些,但是对比结果显示它慢得太多了,让我们非常失望。一开始,我们把责任归结于Lua本身;后来我们怀疑问题出在那些需要序列化整数的操作上。我们使用了一个非常简单的性能分析器(Profiler),与在《Lua程序设计》[3]第23章里描述的那个没什么太大差别。出乎我们意料的是,整数序列化并没有明显拖慢程序的速度,因为并没有太多整数需要序列化;反而是序列化字符串需要对低性能负很大责任。实际上,每一条CORBA消息都包含若干个字符串,即使我们没有显式地操作字符串亦是如此。而且序列化每一条字符串都是一个性能开销巨大的工作,因为它需要创建一个新表,并使用单独的字符填充;然后序列化整个序列,其中需要依次序列化每个字符。一旦我们将字符串序列化作为一种特殊情况(而不是通过通用的序列化流程)重新实现,整个程序的性能就得到了显著的提升。我们只是添加了几行代码,程序的性能已经和C++实现的那个版本有得一拼了[4]。

因此,我们总是应该在优化性能之前进行性能测试。通过测试,才能了解到要优化什么;在优化后再次测试,来确认我们的优化工作确实带来了性能的提升。

一旦你决定必须优化你的Lua代码,本文将可能有所帮助。本文描述了一些优化方式,主要是展示在Lua中怎么做会更慢,怎么做又会更快。在这里,我将不会讨论一些通用的优化技巧,例如优化算法等等——当然,你应该掌握和使用这些技巧,有很多其他地方可以了解这方面的内容。本文主要讨论一些专门针对Lua的优化技巧,与此同时,我还会持续地测试小程序的时间和空间性能。如果没有特别注明的话,所有的测试都在一台Pentium IV 2.9GHz、1GB内存、运行Ubuntu 7.10、Lua 5.1.1的机器上进行。我经常会给出实际的测量结果(例如7秒),但是这只在和其他测量数据进行对比时有意义。而当我说一个程序比另一个快X%时,意味着前者比后者少消耗X%的时间(也就是说,比另一个程序快100%的程序的运行不需要时间);当我说一个程序比另一个慢X%时,则是说后者比前者快X%(意即,比另一个程序慢50%的程序消耗的时间是前者的两倍)。

(0)

相关推荐

  • Lua性能优化技巧(五):削减、重用和回收

    当处理Lua资源时,我们也应该遵循提倡用于地球资源的3R原则--Reduce, Reuse and Recycle,即削减.重用和回收. 削减是最简单的方式.有很多方法可以避免使用新的对象,例如,如果你的程序使用了太多的表,可以考虑改变数据的表述形式.一个最简单的例子,假设你的程序需要操作折线,最自然的表述形式是: 复制代码 代码如下: polyline = {     { x = 10.3, y = 98.5 },     { x = 10.3, y = 18.3 },     { x = 1

  • Lua性能优化技巧(六):最后的提示

    正如我们在前言里所说,优化是一个技巧性很强的工作,从程序是否需要优化开始,有若干个方面的内容需要考量.如果程序真的有性能问题,那么我们应该将精力集中于优化哪里和如何优化. 我们在这里讨论的技巧既不是唯一的,也不是最重要的方面.我们在这里专注于讨论专门针对Lua的优化方式,因为有很多其他的方式可以了解通用的程序优化技巧. 在本文结束之前,我还想介绍两种从更大的尺度上优化Lua程序性能的方式,但是它们都牵涉到Lua代码之外的修改.第一个是使用LuaJIT[1],一个Lua的即时编译器,由Mike P

  • Lua性能优化技巧(二):基本事实

    在运行任何代码之前,Lua都会把源代码翻译(预编译)成一种内部的格式.这种格式是一个虚拟机指令序列,与真实的CPU所执行的机器码类似.之后,这个内部格式将会被由一个包含巨大的switch结构的while循环组成的C代码解释执行,switch中的每个case对应一条指令. 可能你已经在别处了解到,从5.0版开始,Lua使用一种基于寄存器的虚拟机.这里所说的虚拟机"寄存器"与真正的CPU寄存器并不相同,因为后者难于移植,而且数量非常有限.Lua使用一个栈(通过一个数组和若干索引来实现)来提

  • Lua性能优化技巧(四):关于字符串

    与表类似,了解Lua如何实现字符串可以让你更高效地使用它. Lua实现字符串的方式与多数其他脚本语言所采用的两种主要方式都不相同.首先,Lua中的所有字符串都是内部化[1]的,这意味着Lua维护着任何字符串的一个单一拷贝.当一个新字符串出现时,Lua检查是否有现成的拷贝,如果有的话,重用之.内部化使得诸如字符串对比和索引表之类的操作非常快速,但是会降低创建字符串的速度. 第二,Lua中的变量从不存储字符串,只是引用它们.这种实现方式可以加快很多字符串操作,例如在Perl中,当你写类似于$x=$y

  • Lua性能优化技巧(三):关于表

    一般情况下,你不需要知道Lua实现表的细节,就可以使用它.实际上,Lua花了很多功夫来隐藏内部的实现细节.但是,实现细节揭示了表操作的性能开销情况.因此,要优化使用表的程序(这里特指Lua程序),了解一些表的实现细节是很有好处的. Lua的表的实现使用了一些很聪明的算法.每个Lua表的内部包含两个部分:数组部分和哈希部分.数组部分以从1到一个特定的n之间的整数作为键来保存元素(我们稍后即将讨论这个n是如何计算出来的).所有其他元素(包括在上述范围之外的整数键)都被存放在哈希部分里. 正如其名,哈

  • Lua性能优化技巧(一):前言

    和在所有其他编程语言中一样,在Lua中,我们依然应当遵循下述两条有关程序优化的箴言: 原则1:不要做优化. 原则2:暂时不要做优化(对专家而言). 这两条原则对于Lua编程来说尤其有意义,Lua正是因其性能而在脚本语言中鹤立鸡群. 当然,我们都知道性能是编程中要考量的一个重要因素,指数级时间复杂度的算法会被认为是棘手的问题,绝非偶然.如果计算结果来得太迟,它就是无用的结果.因此,每一个优秀的程序员都应该时刻平衡在优化代码时所花费的资源和执行代码时所节省的资源. 优秀的程序员对于代码优化要提出的第

  • Python 性能优化技巧总结

    1.使用测量工具,量化性能才能改进性能,常用的timeit和memory_profiler,此外还有profile.cProfile.hotshot等,memory_profiler用了psutil,所以不能跟踪cpython的扩展: 2.用C来解决费时的处理,c是效率的代名词,也是python用来解决效率问题的主要途径,甚至有时候我都觉得python是c的完美搭档.常用的是Cython,直接把py代码c化然后又能像使用py包一样使用,其次是ctypes,效率最最高的存在,最后还有CPython

  • Python 代码性能优化技巧分享

    如何进行 Python 性能优化,是本文探讨的主要问题.本文会涉及常见的代码优化方法,性能优化工具的使用以及如何诊断代码的性能瓶颈等内容,希望可以给 Python 开发人员一定的参考. Python 代码优化常见技巧 代码优化能够让程序运行更快,它是在不改变程序运行结果的情况下使得程序的运行效率更高,根据 80/20 原则,实现程序的重构.优化.扩展以及文档相关的事情通常需要消耗 80% 的工作量.优化通常包含两方面的内容:减小代码的体积,提高代码的运行效率. 改进算法,选择合适的数据结构 一个

  • php导入大量数据到mysql性能优化技巧

    本文实例讲述了php导入大量数据到mysql性能优化技巧.分享给大家供大家参考.具体分析如下: 在mysql中我们结合php把一些文件导入到mysql中,这里就来分享一下我对15000条记录进行导入时分析与优化,需要的朋友可以参考一下. 之前有几篇文章,说了最近tiandi在帮朋友做一个小项目,用于统计电话号码的,每次按需求从数据库里随机生成打包的电话号码,然后不停地让人打这些电话号码推销产品(小小鄙视一下这样的行为).但是朋友要求帮忙,咱也不能不帮啊,是吧.程序两个星期前已经做好,测试完毕交工

  • LAMP服务器性能优化技巧之Linux主机优化

    目前LAMP (Linux + Apache + MySQL + PHP) 近几年来发展迅速,已经成为Web 服务器的事实标准. LAMP这个词的由来最早始于德国杂志"c't Magazine",Michael Kunze在1990年最先把这些项目组合在一起创造了LAMP的缩写字.这些组件虽然并不是开开始就设计为一起使用的,但是,这些开源软件都可以很方便的随时获得并免费获得.这就导致了这些组件经常在一起使用.在过去的几年里,这些组件的兼容性不断完善,在一起的应用情形变得非常普便.为了改

随机推荐