2024 Clojure 状态调查!中分享您的想法。

欢迎!请查阅关于页面以了解有关此信息。

0
Java 互操作性

标准的 Math.random() 通过声明为同步静态方法而线程安全。

此补丁使用 java.util.concurrent.ThreadLocalRandom,这在简单的单线程 criterium.core/bench 中实际上比普通的 Math.random() 快两倍。

我之所以调查该函数,是为了确保在性能测试多线程负载生成时,随机数生成不是一个瓶颈。

如果需要的话,当然可以根据类 java.util.concurrent.ThreadLocalRandom 的存在来做出条件声明(像 fj-reducers 一样),如果 Clojure 1.7 要与 Java 版本 < 1.7 兼容。

10 个答案

0
_由:claj_发表的评论

当前 rand(clojure 1.6.0)的基准测试,$ java -version
java 版本 "1.7.0_51"
OpenJDK 运行时环境 (IcedTea 2.4.4) (7u51-2.4.4-0ubuntu0.13.10.1)
OpenJDK 64位服务器 VM (构建 24.45-b08, 混合模式)

:jvm-opts ^:replace [] (即不向 JVM 传递任何参数)


(bench (rand 10))                                                                                                                                                                                                                                                       
评估次数:1281673680,样本大小为60,每个样本调用21361228次。                                                                                                                                                                                                                                                    
             平均执行时间:43.630075 纳秒                                                                                                                                                              
    执行时间的标准差:0.420801 纳秒                                                                                                                                                                                                
   执行时间的下四分位数:42.823363 纳秒(2.5%)                                                                                                                                                                          
   执行时间的上四分位数:44.456267 纳秒(97.5%)                                                                                                                                                                      
                   使用开销:3.194591 纳秒                                                                                                                                                           
                                                                                                                                                                                                                                   
在60个样本中找到了1个异常值(1.6667%)                                                                                                                                                                       
        轻度严重        1 (1.6667 %)                                                                                                                            
异常值的影响:1.6389 % 协方差因异常值略微膨胀

Clojure 1.7.0-master-SNAPSHOT.

(bench (rand 10))                                                                                       
评估次数:2622694860 次,取自 60 个样本,每个样本 43711581 次。
             平均执行时间:20.474605 纳秒
   标准偏差:0.248034 纳秒
   下四分位数:20.129894 纳秒(2.5%)
   上四分位数:21.009303 纳秒(97.5%)
             开销:2.827337 纳秒
                                                                                                              
在 60 个样本中找到 2 个异常值(3.3333 %)
        轻度严重        2 (3.3333 %)                                                          
异常值的影响:1.6389 % 协方差因异常值略微膨胀

在 Clojure 1.6.0 上也得到类似的结果,且运行了多个不同测试,结果亦相同。java.util.Random.nextInt 方法非常差劲。ThreadLocalRandom 版本的 .nextInt 方法要好一些,但 rand-int 可以取负整数,这会导致一些争论转换,因为 (.nextInt (ThreadLocalRandom/current) n) 需要上界和下界,而不仅仅是随机数 [0,1) 的简单乘法。

更改:

(.nextDouble (ThreadLocalRandom/current) 参数) 非常迅速,但不能处理负参数。直接乘法的速度约为 30 纳秒。
0

评论者:claj

添加了一些简单的测试来确保rand和rand-int可以接受比率、双精度浮点数和各种类型的负数。真正的测试可能包括重复的生成测试,这些测试主要是为了了解各种论证是否有效等。

0

评论者:claj

0001-rand-using-ThreadLocalRandom-and-tests-for-random.patch包含更改(rand)以及测试用例。

0

评论者:alexmiller

Clojure需要Java 1.6.0,因此以后需要重新考虑这一点。目前我们还没有计划将Clojure 1.7的最低JDK要求提高,但这当然可以改变。

0

评论者:gfredericks

我一直认为,由于无法对PRNG进行播种,因此随机特性在一般情况下效用有限,而使用* } 动态变量将是一种合理的方式。

也许可以通过标准库部分解决这两个问题?我已在https://github.com/fredericksgary/four开始了这一工作,但丛而贡献库可能更容易为所有人标准化。

0

评论者:claj

Gary,我全力支持创建一些精心设计的随机库,这可以作为clojure.core.random库的候选,如果这有用的话。

请看http://code.google.com/p/javarng/,因为这个库似乎做到了你的库four所做到的(以及更多)。可能我们可以从这个库中恢复API、算法或两者。

我将通过邮件联系你!

0
by

评论者:gfredericks

回想起来,clojure.core中的rand变量不应该引入破坏性变更,所以我将为此创建一个工单来看看结果。这至少应该能够解决关于{{binding}}的并发问题。我唯一能想到的反对意见是动态变量的性能问题?

0
by

评论者:gfredericks

新问题在CLJ-1452。

0
by

评论者:jafingerhut

修改日期为2014年5月11日的补丁0001-rand-using-ThreadLocalRandom-and-tests-for-random.patch在第8次提交到Clojure(2014年8月29日)之后无法干净地应用到最后的主分支上。在那一天之前可以干净地应用。

我没有检查更新这个补丁可能容易或困难。见本页面的“更新过时的补丁”部分有关更新补丁的技巧: http://dev.clojure.org/display/community/Developing Patches

0
by
...