Bending the CLOS Mop for Java-Style Single Dispatch
3 months ago
- #Performance Optimization
- #Common Lisp
- #Clojure
- 作者在OpenLDK(一个Common Lisp JVM)上运行Clojure时遇到性能问题,原因是CLOS的多方法分派机制对Java的单分派模型效率低下。
- 解决方案是通过定制CLOS元对象协议(MOP),用单分派模型替换Java方法的分派机制,显著提升了性能。
- 创建了名为`java-generic-function`的新元类,包含用于分派的哈希表缓存和`invokespecial`调用,并添加了线程安全锁。
- `java-generic-function`的定制判别函数通过哈希表查找实现O(1)分派,在首次调用每个接收类后生效。
- 最大性能提升来自拦截PCL的`update-dfun`以清除缓存而非重建判别网络,减少了Clojure启动时的开销。
- 预先用`java-generic-function`元类创建`<init>()`和`clone()`等高频泛型函数,确保从一开始就快速分派。
- 针对Java的`invokespecial`指令(用于构造函数链和`super`调用)添加了独立缓存,进一步优化性能。
- 这些改进将Clojure启动时间从2小时45分钟缩短至2分40秒,证明了MOP定制的有效性。
- 该方案简洁(120行代码)且侵入性小,按照MOP设计初衷实现,无需修改SBCL或运行时系统。