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 ns                                                                                                                                                            
    执行时间标准差:0.420801 ns                                                                                                                                                                                     
   执行时间下四分位数:42.823363 ns (2.5%)                                                                                                                                                                             
   执行时间上四分位数:44.456267 ns (97.5%)                                                                                                                                                                             
                   开销使用:3.194591 ns                                                                                                                                                                                     
                                                                                                                                                                                                                                   
在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版本的性能较好,但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/,因为这个库似乎可以做到你提到的库四的功能(以及更多)。我们可能从这个库中恢复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+Patches

0
by
...