我使用Java编程比使用C++或C变得越来越自在.我希望能够了解使用JVM解释器所产生的性能损失,而不是本机执行相同的"项目".我意识到这里有一定程度的主观性; 该计划的质量将在很大程度上取决于良好的实施.我对一般意义上的以下几个方面感兴趣:
使用解释器时必须有一些开销基线.是否有一些一般的经验法则要记住?10%15%?(我凭空掏出这些数字)我偶尔读过一篇博客,说Java代码几乎和本机代码一样快,但我认为这可能有偏见.
JVM垃圾收集器是否会为运行时性能增加大量开销?我知道Cocoa应用程序已经开始使用垃圾收集模型,我同意它使编程变得更简单,但代价是什么?
从Java进行系统调用的开销是多少?例如,创建Socket对象而不是C套接字API.
最后,我回想一下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块.没有理由说RAII不能用GC语言实现,但它在Java或C#中都不可用
从Java进行系统调用的开销是多少?例如,创建Socket对象而不是C套接字API.
大致相同.为什么会有所不同?当然,Java必须调用相关的OS服务和API,因此只需要一点点开销,但实际上你可能没有注意到这一点.
最后,我回想一下JVM实现是单线程的.如果这是真的(我对此持怀疑态度),这是否意味着Java线程真的不是真正的线程?通常,java线程是否与底层内核提供的线程相对应?Java应用程序是否与本机应用程序来自多个核心/多个CPU的方式相同?
Java可以使用多个线程,是的.JVM 本身可能是单线程的(在所有JVM服务在同一个线程上运行的意义上),我不知道.但是,您的Java 应用程序可以使用任意数量的线程,并且它们将映射到OS线程并将使用多个内核.
有关详细比较,请参阅此处.
Java和C#(以及Objective-C)都没有本机代码快得多的速度。但这仅在您不受工程时间限制的问题时才重要。因为您将有时间用高级语言设计更好的算法。
因此,基本上,如果您要开发的设备每年要制造一百万台,或者是电池供电的,则不要使用java或c#来构建其核心功能。不过,您可以添加一个lisp解释器以使自定义变得容易。微软不会使用c#来表示SQL Server的核心,因为性能确实很重要。另一方面,MS可以期望用户拥有高端硬件的Visual Studio可以用作慢速但高生产率技术的展示。
请注意,我目前在Pharo Smalltalk中进行大部分编程,它比java,c#或Objective-c慢很多,甚至不是最快的Smalltalks之一。生产力胜过绩效。