写点什么

加入 Transients 和 Chunked Sequences 的 Clojure 1.1 更加高效

  • 2009-12-27
  • 本文字数:2104 字

    阅读完需:约 7 分钟

Clojure 1.1 RC1 已经发布——现在是介绍它的时候了,我们希望能够在最终版发布之前给出一些反馈。这些工作是在 GitHub 的 Clojure 1.1 分支上完成的,现在在 Google Code 上已经可以下载到 Clojure 1.1 RC1 的 Binary Package 了。

1.1 的更新日志列出了和 1.0 的不同点,例如在 1.1 发布之前已经关闭的 issue 。同样也加入了一些新的特性来优化 Clojure 程序的性能。

Transients能够大幅改善构建持久数据结构的性能。持久数据结构是Clojure 非常重要的元素,例如隐藏在Clojure 的Vectors,Maps 和Sets(参考Clojure 创建者 Rich Hickey 关于持久数据结构的介绍)后面的细节和概念。简而言之,持久数据结构是非可变的;要删除或者修改数据的唯一办法就是复制一份此数据结构的副本。但是有一个小技巧:持久数据结构的内部结构以及它的性质(所有元素都是不可变的)允许共享所有的数据和大部分结构,因此创建一个拷贝只需要非常小的开销。

虽然复制副本的开销很小,但是也会有需要插入大量元素的情况出现。Transients也可以解决这种情况。简单来说,这种思想就是在大量修改之前将一个持久数据结构转换为一个 transient;调用 transient 即可完成这个功能。同一数据结构的 transient 版提供了和持久版相同的存取函数,但是对于修改操作来说,这就需要使用后缀为“!”的不同函数了,例如 conj!(而不是 conj)。

理解持久数据结构和他们的 transient 版本的关系的一个好办法是看看 java.lang.String 和 java.lang.StringBuilder 之间的关系;一个是不可变的,当需要修改的时候它会创建一个新的副本,而另一个则允许直接在其上进行修改。

不过它们的相似性也就这些。但是,创建一个 StringBuilder 也就意味着拷贝 String 的内容,一个 O(n)的操作。将持久数据结构转换为等价的 transient 版本的开销却非常小:只是一个 O(1)的操作;它只是创建了一个 transient 的对象,这个对象包括了一个数据结构的根对象,然后还有一个表示其为 transient 的标记;不会有数据复制的行为。一旦数据结构的 transient 版本需要转换为持久版,同样也只需要 O(1)的操作。

但是为什么有时候需要将持久版转回为 transient 版呢?难道不能无限制地使用 transient 吗?当然不能 - transient 版本有一个非常重要的限制:它只能被一个线程使用。原因很简单:因为 transient 是可变的,在不同的线程中使用它将会非常危险的,所以需要同步。而持久数据结构使得在线程间共享数据结构变得非常简单;transient 允许一个线程修改数据结构,然后通过将其转换为持久数据结构置为其他线程可访问。

Chunked Sequences是 Clojure 1.1 中的另外一个优化。快速预览可以看 Rich Hickey 关于 chunked sequence 演讲的幻灯片(PDF 格式)。

chunked sequences 背后的思想即是减少由于(lazy)sequences 引入的开销。

Lazy sequences 在 Clojure 中随处可见,它能够延迟某个任务直到必须要去做的时候。但是在某些情况下,有些任务根本不需要做,例如下列代码:

复制代码
(take 10 (range 1 1000000000000) )

range 创建了一个 lazy sequence,这个 lazy sequence 会预生成好指定范围内的 10 个数。然后,take 会请求 10 次 sequence 来获取生成的数。由于使用 lazy 方法,这只是请求了 10 个数而已,因为预处理,所以总共只需计算 10 个数。

实现使用了 lazy-seq 宏(在 core.clj 中),这样使得代码非常简洁。但是有一个问题:在 lazy sequence 中访问下一个元素可能会有一些数据管理上的开销。Chunked sequences 即是为了减少这样的开销而生的,它将元素划分成多个块并且缓存值;块的大小是 32,也就是说每一步的开销只是限定在 32 个元素之内。

另外一种优化 chunked sequences 的方法是对数据结构内部组织结构分析。例如,一个持久 vector 是以树的形式组织的,在这里面数据保存在 32 个元素数组中。为了访问一个元素,需要遍历这棵树来寻找到元素保存的数组。一个原生的 sequence 使用索引访问下一个元素,这样可能导致每次访问的时候都需要遍历树。chunked sequence 的持久 vector 实现避免了这种情况:它找到 sequence 开始的存储有 32 个元素的数组,然后为每个元素快速建立一个简单索引;只有在 32 个元素都访问之后,才需要取下一个树节点并且开始遍历。

现在就只是看看 chunked sequences 的接受度如何了;它们显然有着很大的优点,但是 Clojure 1.1 更新日志指出:

chunked-seq 的开销和其他 sequence 一样都是完全透明的。但是,注意有些 sequence 一次会处理超过 32 个元素。如果你依赖于完全惰性(full laziness),不希望学习如何生成任何零成本的结果,那么当然可能对你有影响。一个将开销限制在单个元素的 chunked-seq 的接口仍然在设计中,请将 chunked sequence 在实际应用中出现的问题或者行为差异反馈给我们。

当然 Clojure 1.1 还有更多特性仍待介绍,更多信息请参考 Clojure 1.1 更新日志

如果需要更多关于 Clojure 的信息,请点击 InfoQ 的 Clojure 标签。强烈推荐 Rich Hickey 的演讲,例如持久性数据结构和已托管的引用。InfoQ 同样也有在 QCon London 2009 上采访 Rich Hickey 的视频

查看英文原文: Clojure 1.1 Adds Transients, Chunked Sequences for Efficiency

2009-12-27 05:171544
用户头像

发布了 90 篇内容, 共 34.8 次阅读, 收获喜欢 5 次。

关注

评论

发布
暂无评论
发现更多内容

计时与任务管理软件RH Timer pro for Mac

Mac相关知识分享

SyncBird Pro for Mac(iPhone文件管理器)v4.1.5激活版

iMac小白

AB Micro850笔记 LD 反向接触与反向线圈

万里无云万里天

自动化 PLC 工厂运维

AB Micro850笔记 LD 指令块选择器与替换指令

万里无云万里天

自动化 PLC 工厂运维

Omni Recover for Mac(iPhone数据恢复工具)v3.7.5激活版

iMac小白

AB Micro850笔记 使用ccw详细了解PLC信息

万里无云万里天

自动化 PLC 工厂运维

专业音频格式转换软件dBpoweramp Music Converter for Mac

Mac相关知识分享

软件

AB Micro850笔记 LD 字符串处理

万里无云万里天

自动化 PLC 工厂运维

AB Micro850笔记 LD 直接接触与直接线圈

万里无云万里天

自动化 PLC 工厂运维

AB Micro850笔记 RSLinx 通信配置

万里无云万里天

自动化 PLC 工厂运维

Wirecast Pro for Mac(视频直播制作工具)v16.3.0中文免激活版

iMac小白

Bookends for Mac(文献书籍管理工具)v15.0.7注册激活版

iMac小白

AB Micro850笔记 LD 逻辑运算 与或非异或

万里无云万里天

自动化 PLC 工厂运维

Privatus for Mac(网页缓存清理工具)v7.1.1激活版

iMac小白

Python 命名元组:让你的数据结构更具可读性与可维护性!

LLLibra146

Python namedtuple

AB Micro850笔记 使用ccw了解扩展与插件信息

万里无云万里天

自动化 PLC 工厂运维

AB Micro850笔记 LD 加减乘除 取整取反取余绝对值

万里无云万里天

自动化 PLC 工厂运维

技术文档管理系统精选10款:如何挑选适合您的工具

爱吃小舅的鱼

技术文档管理

全面解析10款文档结构化管理系统,赋能企业数字化转型

爱吃小舅的鱼

文档管理 文档结构化管理

AB Micro850笔记 使用ccw粗略了解PLC信息

万里无云万里天

自动化 PLC 工厂运维

AB Micro850笔记 LD 比较大于小于 高低限值最大最小

万里无云万里天

自动化 PLC 工厂运维

AB Micro850笔记 LD 设置线圈与重设线圈

万里无云万里天

自动化 PLC 工厂运维

AB Micro850笔记 CCW F1 查看本地帮助文档

万里无云万里天

自动化 PLC 工厂运维

AB Micro850笔记 ccw中能添加的设备一览

万里无云万里天

自动化 PLC 工厂运维

终端仿真软件ZOC8 for Mac

Mac相关知识分享

跨平台 SQL 编辑器和数据库查询工具RazorSQL for Mac

Mac相关知识分享

dBpoweramp Music Converter for Mac(音频格式转换器)R2024.09.30直装版

iMac小白

Hides for Mac(隐藏程序Mac老板键)v6.0.1激活版

iMac小白

UE5+ChatGPT实现3D AI虚拟人综合实战

陆通

大模型RAG:文档分块方案与RAG全流程

程序员架构进阶

大模型 10月月更 rag 大模型应用

AB Micro850笔记 ccw 变量导出功能

万里无云万里天

自动化 PLC 工厂运维

加入Transients和Chunked Sequences的Clojure 1.1更加高效_Java_Werner Schuster_InfoQ精选文章