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))                                                                                                                                                                                                                                                                                                                        
评估次数:在21361228次调用中的60个样本中为1281673680次。                                                                                                                                                                       
             平均执行时间: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纳秒(25%)
执行时间上限四分位数: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进行种子,因此随机功能在一般情况下用途有限,而动态var的方式是合理的。

也许可以通过标准库部分解决这两个问题?我在https://github.com/fredericksgary/four开始了尝试,但似乎贡献库更容易让大家标准化。

0

评论者:claj

Gary,我完全支持创建一个精心设计的随机库,这可能成为clojure.core.random的候选库,如果那样有用的话。

请查看http://code.google.com/p/javarng/,因为这个库似乎与您库会做类似的事情(甚至是更多)。也许我们可以从这个库中抢救出API、算法或两者。

我将通过邮件与您联系!

0

评论者:gfredericks

再想想,clojure.core中的“rand”变量不应破坏兼容性,所以我会为这个问题提交一个工单,看看情况如何。至少这应该可以解决使用{{binding}}时的并发问题。我所想到的唯一反对意见是动态变量的性能问题吗?

0

评论者:gfredericks

新问题在CLJ-1452。

0

评论者:jafingerhut

修改2014年5月11日的补丁0001-rand-using-ThreadLocalRandom-and-tests-for-random.patch在2014年8月29日对Clojure进行了提交后不再干净地应用于最新主分支。在那之前它已经可以干净应用。

我没有检查更新这个补丁的难易程度。请参阅该维基页面上的“更新过时的补丁”部分,以获取有关更新补丁的提示:http://dev.clojure.org/display/community/Developing Patches

0
...