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线程,并且将使用多个内核。



