加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala perf:为什么Scala应用程序比等效的Java应用程序慢30倍?

发布时间:2020-12-16 09:17:23 所属栏目:安全 来源:网络整理
导读:我是一个非常熟练的C#开发人员,但需要开始编写适用于JVM的代码.与C#相比,Java语言的功能较差,所以我对Scala提供的功能感兴趣. 然而,在Scala听到的时候,所有的运算符都是简单的方法,我对于数学计算的性能影响(这对我的团队写的应用程序类型很重要)变得怀疑,
我是一个非常熟练的C#开发人员,但需要开始编写适用于JVM的代码.与C#相比,Java语言的功能较差,所以我对Scala提供的功能感兴趣.

然而,在Scala听到的时候,所有的运算符都是简单的方法,我对于数学计算的性能影响(这对我的团队写的应用程序类型很重要)变得怀疑,

所以我运行了一些简单的基于int的测试,发现Scala比同等的Java代码慢约30倍.不好!有谁能告诉我我做错了什么?或者如何提高Scala示例的计算性能与Java相当?

UPDATE1:正如前两个答案所指出的那样,我是一个超级noob并在IntelliJ IDE中运行它.我不知道如何通过java命令行运行scala应用程序,这可能是一个IntelliJ的问题.感谢帮助的人,在继续执行测试之前,我需要调查简单的命令行执行scala,因为IDE给出的结果显然是不准确的.

更新2:Luigi在IntelliJ的评论中表示,他获得了相同的时间,所以似乎我的野蛮差异不是由于IntelliJ?关于这可能是什么的其他想法?我会尝试通过命令行运行,并发布更新与我的结果.

UPDATE3:
通过命令行运行后,我得到相同的30x的差异.
我的电脑是一个3核AMD x64 3.4Ghz,运行J2SE 6 jdk 64bit 1.6.0_31,Window7.

这是我的运行时间:
Java:210ms.
Scala:2000至7400ms(一般为7000范围)

所以,我想这个问题还是开放的.为什么Scala在我的平台上跑得这么慢?有什么与java 64位运行时,还是用Java 6?

运行时版本:

C:Usersjason>java -showversion
java version "1.6.0_31"
Java(TM) SE Runtime Environment (build 1.6.0_31-b05)
Java HotSpot(TM) 64-Bit Server VM (build 20.6-b01,mixed mode)

C:Usersjason>scala
Welcome to Scala version 2.9.1-1 (Java HotSpot(TM) 64-Bit Server VM,Java 1.6.0_31).

更新4,而我的原始测试有30倍的差异,将迭代增加到100000000导致差异缩小到约33%,所以似乎scala仍然被我的机器上的一些未知的初始化成本所主导.我会用最高级别的答案关闭这个,因为我不认为我们会发现性能问题,因为没有人,除了我看到问题:(

*更新5,解决方案:根据我得到的2个答案的帮助,我想出了这个问题,请看下面我的答案更多的细节(总结:第一次调用System.nanoTime()需要很长时间)*

以下是我的示例应用程序:

//scala
object HelloWorld {
  //extends Application {
  def main(args: Array[String]) {
    println("hello scala")
    var total: Long = 0
    var i: Long = 0
    var x: Long=0;
    //warm up of the JVM to avoid timing of runtime initialization
    while (i < 100000)
    {
      x=i;
      x += x - 1;
      x -= x + 1;
      x += 1;
      x -= 1;
      total += x;
      i+=1;
    }
    //reset variables
    total = 0
    i = 0;
    //start timing
    var start: Long = System.nanoTime

    //run test
    while (i < 100000) {
      x=i;
      x += x - 1;
      x -= x + 1;
      x += 1;
      x -= 1;

      total += x;
      i+=1;
    }
    var end: Long = System.nanoTime
    System.out.println("ms,checksum = ")
    System.out.println((end - start) / 1000)
    System.out.println(total)
  }
}

这里是java的等效,速度要快30倍

//java
public class app {
    public static void main(String[] args)
    {
        String message = "hello,java";
        System.out.println(message);
        long total = 0;
        //warm up of the JVM to avoid timing of runtime initialization
        for(long i=0;i< 100000;i++)
        {
            long x=i;
            x+=x-1;
            x-=x+1;
            x++;
            x--;
            total+=x;
        }
        //reset variables
        total = 0;
        //start timing and run test
        long start = System.nanoTime();
        for(long i=0;i< 100000;i++)
        {
            long x=i;
            x+=x-1;
            x-=x+1;
            x++;
            x--;
            total+=x;
        }
        long end = System.nanoTime();
        System.out.println("ms,checksum = ");
        System.out.println((end-start)/1000);
        System.out.println(total);
    }
}

解决方法

所以,我想我自己弄清楚了答案.

问题是在调用System.nanoTime.这样做有一些初始化成本(加载Java基本库等),从Java运行时调用时比从Scala运行时加载更便宜.

我通过改变总的初始值来证明这一点,而不是设置它

var total: Long = System.nanoTime()

这是在第一个“预热”循环之前添加的,并且这样做现在使得应用程序的两个版本(Java和Scala)同时运行:约2100次迭代.

感谢你们的帮助,如果没有你的帮助,我也不会想到这一点.

ps:我会离开“接受的答案”,因为我没有在没有帮助的情况下跟踪它.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读