当前位置: 首页 > 面试题库 >

Java运行时性能与本机C / C ++代码?

韦胜泫
2023-03-14
问题内容

与使用C
++或C相比,使用Java进行编程变得越来越舒适。我希望能感觉到使用JVM解释器引起的性能下降,而不是本地执行相同的“项目”。我意识到这里有一定程度的主观性。程序的质量将在很大程度上取决于良好的实施。我对一般意义上的以下方面感兴趣:

  • 使用解释器时,必须有一些开销基线。有一些一般的经验法则要记住吗?10%15%?(我凭空想出了这些数字)我读过偶尔的博客,指出Java代码几乎与本地代码一样快,但是我认为这可能是有偏见的。

  • JVM垃圾收集器是否会显着增加运行时性能的开销?我知道Cocoa应用程序已经开始使用垃圾回收模型,并且我同意它使编程变得简单得多,但是要付出什么代价呢?

  • 从Java进行系统调用的开销是多少?例如,创建一个与C套接字API相对的Socket对象

  • 最后,我记得在某处读到JVM实现是单线程的。如果这是真的(我对此表示怀疑),这是否意味着Java线程确实不是真正的线程?通常,Java线程是否对应于底层内核提供的线程?Java应用程序是否可以像本机应用程序从多个核心/多个cpu中受益一样?

来自开发人员的任何了解JVM和Java程序性能复杂性的建议都将不胜感激。谢谢。


问题答案:

Java不是一种解释型语言,并且没有用于多个版本。Java字节码是即时进行JIT处理的。(从技术上讲,它仍然会解释一些代码,但是任何在性能方面重要的事情都会得到JIT处理)

至于性能,到底有什么让您疯狂地想到“存在开销的基线”?没有。从来没有,永远也不会。不在C 和Java之间,也不在Python和Javascript或
任何 其他两种语言之间。在某些情况下,特定版本的JVM的性能将比特定的C
编译器的性能更快,并且特定的C ++编译器的性能将优于特定的JVM。

因此,您所选择的语言的“开销”完全取决于1)您希望代码执行的操作,以及2)您如何编写代码。

如果您使用Java程序并将其转换为C ++,则结果几乎肯定会变慢。

如果您使用C ++程序并将其转换为Java,则运行速度也会变慢。

并不是因为一种语言比另一种语言“更快”,而是因为原始程序是为一种语言编写的,并且经过精心设计以适合
种语言。将其翻译成另一种语言的任何尝试都会失去这一优势。您最终得到的是C 风格的Java程序(无法在JVM上高效运行)或Java风格的C
程序(也将同样运行得 很差)

两种语言规范均未包含“结果必须比语言y慢至少x%”的子句。您的C ++编译器和JVM都竭尽所能,以使事情快速发展。

然后,您今天看到的性能特征明天可能会改变。语言没有速度。

但要回答您的特定问题:

使用解释器时,必须有一些开销基线。有一些一般的经验法则要记住吗?10%15%?我偶尔读过一篇博客,指出Java代码几乎与本地代码一样快,但是我可能对此有偏见。

如上所述,这取决于。对于许多常见任务,您通常不会以任何方式看到超过百分之几的差异。对于某些用例,您会看到更大的差异(无论哪种方式。两种语言在性能方面都有优势。JVM有一些开销,但也有巨大的优化机会,尤其是垃圾收集器)

JVM垃圾收集器是否会显着增加运行时性能的开销?我知道Cocoa应用程序已经开始使用垃圾回收模型,并且我同意它使编程变得简单得多,但是要付出什么代价呢?

基本上没有。平均而言,由于许多原因,垃圾收集器比手动内存管理要 快得多

  • 在托管堆上,可以更快地完成动态分配
  • 共享所有权的摊销成本可以忽略不计,在这种情况下,您必须以母语使用引用计数,这非常昂贵
  • 在某些情况下,对象销毁也大大简化了(大多数Java对象可以通过GC’内存块来回收。在C ++中,析构函数必须 始终 执行,几乎每个对象都有一个)

GC的主要问题在于,尽管平均而言垃圾回收器的性能更好,但是您却无法控制 何时
获取性能成本。手动内存管理可确保您在等待清理内存时不会暂停线程。垃圾收集器几乎可以在任何时候决定暂停该进程并清理内存。在几乎所有情况下,这都足够快,这毫无疑问,但是对于至关重要的实时资料而言,这是一个问题。

(另一个问题是您失去了一些表达能力。在C
++中,RAII用于管理各种资源。在Java中,您不能使用RAII。相反,GC为您以及所有其他资源处理内存,您很麻烦,必须自己尝试很多try /
finally块。没有理由不能以GC语言编写RAII,但是Java或C#都不提供RAII)

从Java进行系统调用的开销是多少?例如,创建一个与C套接字API相对的Socket对象。

大致相同。为什么会有所不同?当然,Java必须调用相关的OS服务和API,因此只需要一点点开销,但是实际上您可能不会注意到。

最后,我记得在某处读到JVM实现是单线程的。如果这是真的(我对此表示怀疑),这是否意味着Java线程确实不是真正的线程?通常,Java线程是否对应于底层内核提供的线程?Java应用程序是否可以像本机应用程序从多个核心/多个cpu中受益一样?

Java可以使用多个线程,是的。JVM 本身 可能是单线程的(从某种意义上说,所有JVM服务都在同一线程上运行),我对此一无所知。但是您的Java
应用程序 可以使用任意数量的线程,并且它们映射到OS线程,并且将使用多个内核。



 类似资料:
  • 这个问题继续我的问题(根据神秘主义者的建议): C代码循环性能 继续我的问题,当我使用压缩指令而不是标量指令时,使用内部函数的代码看起来非常相似: 该内核的测量性能约为每个周期5.6个FP操作,尽管我预计它的性能恰好是标量版本的4倍,即每个周期4.1,6=6,4个FP操作。 考虑到权重因素的变动(感谢您指出),时间表如下所示: 虽然在movss操作之后有一条额外的指令将标量权重值移动到XMM寄存器

  • 问题内容: 我正在研究Swift及其与Objective-C的区别。据我所知,Swift的当前版本相当快,甚至比Objective- C还快:请参见此处。 但是,由于大多数测试都是使用排序算法等完成的,所以我想知道,当Swift用于iOS应用开发时,它实际上是否会比Objective- C更快。任何人都可以(最好是从他们自己的经验中)启发我。 问题答案: 有一篇很棒的博客文章,特别是关于Swift

  • 本文向大家介绍golang、python、php、c++、c、java、Nodejs性能对比,包括了golang、python、php、c++、c、java、Nodejs性能对比的使用技巧和注意事项,需要的朋友参考一下   本人在PHP/C++/Go/Py时,突发奇想,想把最近主流的编程语言性能作个简单的比较, 至于怎么比,还是不得不用神奇的斐波那契算法。可能是比较常用或好玩吧。   好了,tal

  • 问题内容: 现在我有了一些C源代码,我想在我的Java应用程序中使用它。我需要执行C源代码,并将结果返回到我的Java应用程序。与其将所有C源代码重写为Java,我如何在Java应用程序中重用C源代码? 问题答案: 看一下Java Native Interface 。 Java本机接口(JNI)是一种编程框架,它使Java虚拟机(JVM)中运行的Java代码能够被本机应用程序(特定于硬件和操作系统

  • 我目前正在wpf中重新编码我的Epic-Games-Launcher一样的项目(因为它在WinForm中看起来像垃圾),但是为了制作旧版本,我硬编码了所有的游戏页面。我想通过使用webBrowser下载字符串(这是HTML代码)并加载它来绕过这个问题,但现在我有一个问题,我不知道如何从HTML文件运行C#代码。我会很乐意得到任何帮助。 编辑:我也可以考虑加载一个xaml文件。

  • 问题内容: 我有一个分配大量内存的应用程序,我正在考虑使用一种比malloc更好的内存分配机制。 我的主要选择是:jemalloc和tcmalloc。使用它们中的任何一个有什么好处吗? http://locklessinc.com/benchmarks.shtml中的某些机制(包括作者的专有机制- 无锁)之间有很好的比较, 并提到了每种机制的利弊。 鉴于这两种机制都是活跃的,并且会不断完善。是否有