一项通用的编程技术:用空间换时间。

  例如有一种做法就可以提高一些函数的运行速度,记录下函数计算的结果,当再次调用该函数时,便可以复用之前的结果。

比如,一个普通服务器,在它收到请求中包含Lua代码,会loadstring,编译出新函数。为了避免反复loadstring,用一个辅助table保存编译结果。

local results = {}    --辅助的table,记录所有loadstring的结果
function mem_loadstring(s)
local res = results[s]
if res == nil then --是否记录过
res = assert(loadstring(s)) --计算新结果
results[s] = res --存下以备之后复用
end
return res
end

table results会逐渐地积累服务器收到的所有命令及其编译结果。经过一段时间后,这种累积会耗费服务器内存。

弱引用的table可以解决这个问题。如果result table具有弱引用的value,那么每次垃圾收集都会删除所有在执行时未使用的编译结果。

local results = {}
setmetatable(results, {__mode = "v"}) --使value成为弱引用,由于key是字符串,也可以把table变成完全弱引用 __mode = "kv"
function mem_loadstring(s)
<as before>

“备忘录”技术还可以用于确保某类对象的唯一性。

假设一个系统用table来表示颜色,其中3个字段red,green和blue具有相同的取值范围。最简单的颜色生成函数是:

function createRGB(r , g , b)
return {red = r , green = g, blue = b}
end

通过备忘录技术,可以复用具有相同颜色的table,备忘录table的key可以根据颜色分量来生成:

local results = {}
setmetatable(results, {__mode = "v"}
function createRGB(r , g , b )
local key = r .. "-" .. g .. "-" .. b  --字符串作为唯一的key,可以通过原始的相等性操作符比较
local color = results[key]
if color == nil then
color = {red = r , green = g, blue = b}
results[key] = color
end
return color
end

若两种颜色相同,那么它们必定是由同一个table表示的。

只要一种颜色正在使用,就不会被清除出results,只要一个颜色未被清除,它就可与颜色进行比较,它的表示也可作为后续调用来复用。

以上内容来自:《Lua程序设计第二版》和《Programming in Lua  third edition 》

Chapter 17_2 备忘录函数的更多相关文章

  1. Chapter 21_2 模式匹配函数

    基础函数比较简单,就是几个普通的函数string.byte.string.char.string.rep.string.sub.string.format还有大小写转换函数upper和lower. 接 ...

  2. Chapter 21_1 字符串函数

    接下来开始接触Lua强大的字符串处理能功能——字符串库. 原始的Lua解释器操作字符串的能力很有限,真正强大的能力还是来自字符串库. 它所有的函数都在模块string中.它还为strings设置了一个 ...

  3. Chapter 15_1 require函数

    Lua提供了一个名为require的高层函数来加载模块,但这个函数只假设了关于模块的基本概念. 对于require而言,一个模块就是一段定义了一些值(函数或者包含函数的table)的代码. 为了加载一 ...

  4. Lua学习笔记一

    学习了有一周多了.之前一直不想献丑,但还是记录下这个过程. 第1章  开发软件搭建 1. ubuntu 下lua安装 sudo apt-get install lua5.1 2.win下的环境搭建. ...

  5. Lua弱引用table

    弱引用table 与python等脚本语言类似地,Lua也采用了自动内存管理(Garbage Collection),一个程序只需创建对象,而无需删除对象.通过使用垃圾收集机制,Lua会自动删除过期对 ...

  6. Unity3D脚本中文系列教程(十)

    http://dong2008hong.blog.163.com/blog/static/4696882720140312627682/?suggestedreading&wumii Unit ...

  7. Cocos2d-x数据持久化-修改数据

    修改数据时,涉及的SQL语句有insert.update和delete语句,这3个SQL语句都可以带参数.修改数据的具体步骤如下所示.(1) 使用sqlite3_open函数打开数据库.(2) 使用s ...

  8. Cocos2d-x数据持久-变更数据

    当数据变化,参与SQL报表insert.update和delete声明.这项3个月SQL语句可以带参数. 详细过程的数据,例如,下面的变化看出.(1) 采用sqlite3_open开放式数据库功能.( ...

  9. C++ one more time

    写在前面:我们学习程序设计的方法先是模仿,然后举一反三.在自己的知识面还没有铺开到足够解决本领域的问题时,不要将精力过分集中于对全局无足轻重的地方!!! 以下参考钱能老师的<C++程序设计教程 ...

随机推荐

  1. IOS研究院之打开照相机与本地相册选择图片(六)

    原创文章如需转载请注明:转载自雨松MOMO程序研究院本文链接地址:IOS研究院之打开照相机与本地相册选择图片(六) Hello 大家好 IOS的文章好久都木有更新了,今天更新一篇哈. 这篇文章主要学习 ...

  2. 鸟哥的LINUX私房菜基础篇第三版 阅读笔记 三 Linux磁盘与文件系统管理

    一.认识EXT2文件系统:     a.硬盘的组成:转动小马达+存储的磁盘+读写的机械臂     b.磁盘的一些概念              扇区为最小的物理储存单位,每个扇区为512B       ...

  3. Git命令行连Github与TortoiseGit 连Github区别

    如果是用git 通过命令行的方式连接github,那么只需要通过命令 $ ssh-keygen -t rsa -C "your_email@youremail.com" 生成rsa ...

  4. JAVA小知识点-Finally和Return的执行关系

    如果Try和Catch中存在return语句的时候Finally内的语句是否会执行,执行的时候对结果又有什么影响呢?我写了个例子来试验这个问题: public static Map<String ...

  5. linuxmint 15/ ubuntu 13.04 install OpenERP client 6.0.4

    As we all know OpenERP is a great open-source ERP/CRM project. It does help people a lot when workin ...

  6. 异常分析:关于jsp页面使用jstl

    1.在jsp页面中使用如下代码加入jstl的支持 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/c ...

  7. .Net程序员学用Oracle系列(2):准备测试环境

    <.Net程序员学用Oracle系列:导航目录> 本文大纲 1.创建说明 1.1.为什么要创建的测试环境? 1.2.了解 Oracle 实例的默认用户 2.创建环境 2.1.创建基本环境 ...

  8. 读书笔记:《HTML5开发手册》--现有元素的变化

    读书笔记:<HTML5开发手册>-- 现存元素的变化 继续学习HTML5语义化的内容,今天主要介绍一下,HTML5之前的元素经HTML5规范后的语义及一些使用示例. 一.cite HTML ...

  9. Windows平台下安装Eclipse插件,开发Hadoop应用

    欢迎和大家交流技术相关问题: 邮箱: jiangxinnju@163.com 博客园地址: http://www.cnblogs.com/jiangxinnju GitHub地址: https://g ...

  10. js操作

    1.1.直接传入Javascript代码,定位元素 js可以点击页面上不显示暂时隐藏(比如下拉列表),但是html文件中存在的属性 WebDriver driver = new FirefoxDriv ...