猿问

对 Java、Groovy、Jython 和 Python 进行基准测试

我正在尝试对 PI (3.14159) 飞镖的蒙特卡洛计算进行基准测试。我已经用 Java、Groovy、BeanShell、Julia、Jython 和 Python(Python2 用 C 实现)实现了我的代码。


这是我的原始 Java 代码“MonteCarloPI.java”:


import java.util.Random; 


public class MonteCarloPI {

     public static void main(String[] args)

       {

         int nThrows = 0;

         int nSuccess = 0;

         double x, y;

         long then = System.nanoTime();

         int events=(int)1e8;

         Random r = new Random(); 

         for (int i = 0; i < events; i++) {

            x = r.nextFloat();      // Throw a dart

            y = r.nextFloat();

            nThrows++;

            if ( x*x + y*y <= 1 )  nSuccess++;

       }

 double itime = ((System.nanoTime() - then)/1e9);

 System.out.println("Time for calculations (sec): " + itime+"\n");

 System.out.println("Pi = " + 4*(double)nSuccess/(double)nThrows +"\n");

      }

}

这是文件“MonteCarloPI.groovy”中的 Groovy 代码:


import java.util.Random


int nThrows = 0

int nSuccess = 0

double x, y

long then = System.nanoTime()

int events=1e8

r = new Random()

for (int i = 0; i < events; i++) {

            x = r.nextFloat()      // Throw a dart

            y = r.nextFloat()

            nThrows++

            if ( x*x + y*y <= 1 )  nSuccess++

}

itime = ((System.nanoTime() - then)/1e9)

System.out.println("Time for calculations (sec): " + itime+"\n")

System.out.println("Pi = " + 4*(double)nSuccess/(double)nThrows +"\n")

       

或者,我删除了诸如“float”和“int”(即松散类型)之类的定义。这使用“松散”类型检查性能。


我已将“MonteCarloPI.groovy”重命名为 BeanShell 脚本文件“MonteCarloPI.bsh”(BeanShell 的语法与 Groovy 非常相似)


对于标准 Python 语言,代码“MonteCarloPI_CPython.py”如下所示:


import random,time


nThrows,nSuccess = 0,0

then = time.time()

events=int(1e8)

for i in xrange(events):

   x,y = random.random(),random.random();   # Throw a dart                   

   nThrows +=1

   if ( x*x + y*y <= 1 ):  nSuccess+=1

itime = time.time() - then

print ("Time: ",itime,"sec Pi = ",4*nSuccess/float(nThrows))

此代码在 CPython 2.7.18(用 C 实现的 Python)或 Jython 2.7.2(Java 实现)中执行。对于 Python 3.8.3(“Python3”),将“xrange”替换为“range”。

千万里不及你
浏览 193回答 2
2回答

人到中年有点甜

不错的作品。有趣的比较你已经到了那里。作为一名 python 开发人员,我想添加一些关于 Python 的额外视图。我认为它较慢主要是因为动态类型。另一个原因是您正在计算标量值(即使用 for 循环并一次计算一个数字)。Python 的优点之一是使用 NumPy 库的向量计算(这允许同时计算多个数字)。所以,这是我的算法实现。注意:我使用的是 python 3.6。import numpy as npimport timestart = time.time()events = int(1e8)nThrows, nSuccess = 0, 0x, y = np.random.uniform(size=(2, events))nSuccess = (x*x + y*y <= 1).sum()nThrows = eventspi = 4*nSuccess/float(nThrows)stop = time.time()print('Time: {}, Pi = {}'.format(stop-start, pi))以下是我的 i7 x64 计算机 (Windows 10) 上的基准测试结果:Python (original code):&nbsp; &nbsp; &nbsp; 42.6s&nbsp; Pi = 3.1414672Python (my optimized code):&nbsp; 4.7s&nbsp; &nbsp;Pi = 3.1417642如您所见,在我的计算机上运行的原始 python 代码比您计算机上的 python 代码慢。因此,优化后的版本可能比 Java 或 Groovy 更快。希望这可以帮助。

慕斯709654

对于 Julia 代码,您在基准测试中包含编译时间。另一件需要注意的事情是您正在使用全局变量,众所周知这会降低性能。使用您的基准版本,我的机器上的执行时间是 17.7 秒。将所有内容移到一个函数中,我得到了 0.83 秒。从中删除编译时间使我降至 713.625 毫秒。我的代码的最终版本是这个(注意你在循环中计算了一个太多)。using Randomusing BenchmarkToolsfunction benchmark()&nbsp; &nbsp; nThrows = 0&nbsp; &nbsp; nSuccess = 0&nbsp; &nbsp; events = 100_000_000&nbsp; &nbsp; for j in 1:events&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x = rand()&nbsp; &nbsp; &nbsp; #&nbsp; Throw a dart&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; y = rand()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; nThrows += 1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if&nbsp; x^2 + y^2 <= 1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; nSuccess += 1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; end&nbsp; &nbsp; end&nbsp; &nbsp; 4.0*nSuccess/nThrowsendpi = @btime benchmark()println( "Pi = ",&nbsp; pi)请注意,进一步的改进是可能的。在循环之外分配一个随机数数组而不是每次迭代调用 rand 两次可能是有益的。您可以在此处找到其他性能提示:https ://docs.julialang.org/en/v1/manual/performance-tips/
随时随地看视频慕课网APP

相关分类

Java
我要回答