2024年Clojure状态调查分享你的想法。

欢迎!请查看关于页面以获得更多关于这是如何工作的信息。

0
Java互操作

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

补丁使用java.util.concurrent.ThreadLocalRandom,这在简单的单线程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))                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
评估次数:60个样本中的21361228次调用,共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纳秒(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进行种子,因此一般的随机性能用有限,而动态var*被认为是一个合理的解决方案。

也许这两个问题可以通过标准库部分解决。我在https://github.com/fredericksgary/four上开始了一个项目,但假设一个贡献库对大家来说更容易标准化。

0

评论者:claj

Gary,我非常支持创建一个精心设计的随机库,这可能是clojure.core.random库的一个候选,如果有用的话。

请查看http://code.google.com/p/javarng/,因为似乎这个库的功能与您的库非常相似(还更多)。我们可能可以从这个库中拯救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在2014年8月29日对Clojure进行了一些提交后,不再干净地应用到最新的master版本。在此之前它可以干净地应用。

我没有检查更新此补丁可能有多容易或多困难。请参阅此维基页面上的“更新旧的补丁”部分,其中有关于更新补丁的一些建议:http://dev.clojure.org/display/community/Developing Updates

0
by
...