一种。今天的Java速度与C ++相比如何?
难以测量。值得注意的是,实现速度的主要部分,即内存分配器,是Java和C ++中非常不同的算法。与C ++的确定性内存管理相比,收集器的非确定性本质使获取有意义的性能数据变得极为困难,因为您永远无法确定收集器所处的状态。这意味着编写基准非常困难。可能会对它们进行有意义的比较。有些内存分配模式在GC上运行得快得多,有些在本地分配器上运行得快得多。
但是,我要说的是Java GC必须在每种情况下都能快速运行。但是,可以将本机分配器换成更合适的分配器。我最近在SO上提出了一个问题,即Dictionary
与同等条件相比,为什么C#可以在(我的计算机上为0.45毫秒)内执行std::unordered_map
执行时间为10ms(在我的计算机上)。但是,通过简单地将分配器和哈希交换出更合适的分配器,我将我的机器上的执行时间减少到0.34ms,这是原始运行时间的三十分之一。您永远都不会希望使用Java执行这种自定义优化。可以真正发挥作用的一个很好的例子是线程。当处理许多线程上的许多分配时,诸如TBB之类的本地线程库提供了线程缓存分配器,该分配器比传统分配器快得多。
现在,许多人将谈论JIT的改进以及JIT如何获得更多信息。当然可以。但是,它距离C ++编译器所能提供的功能还差得很远,因为从最终程序运行时的角度来看,编译器具有无限的运行时间和空间。JIT花费在思考如何最好地优化程序上的每个周期和每个字节,就是程序不花时间执行并且不能用于自身内存需求的周期。
此外,在某些情况下,编译器和JIT优化总是无法证明某些优化,尤其是在诸如转义分析之类的情况下。在C ++中,然后作为值是在堆栈上无论如何,编译器不需要执行它。此外,还有一些简单的事情,例如连续内存。如果您使用C ++分配数组,则分配一个连续的数组。如果您使用Java分配数组,那么它根本就不是连续的,因为该数组仅填充有指向任何地方的指针。这不仅是双重间接访问的内存和时间开销,而且也是缓存开销。这种事情就是Java语言语义仅仅要求它必须比等效的C ++代码慢的地方。
最终,我的个人经验是,Java的速度平均只能达到C ++的一半。但是,由于所涉及的算法根本不同,实际上如果没有非常全面的基准套件就无法备份任何性能声明。
b。是否可以使用Java创建现代AAA标题?
我认为您的意思是“游戏”,而不是机会。首先,由于几乎所有现有的库和基础结构都以C ++为目标,因此您必须从头开始编写所有内容。尽管它本身并没有使它不可能,但是它肯定会为不可行做出坚实的贡献。其次,即使C ++引擎也几乎无法适应现有控制台的微小内存限制-如果这些控制台甚至存在JVM-并且PC游戏玩家期望它们的内存更多。在C ++中创建高效的AAA游戏已经足够困难了,我不知道如何用Java来实现。没有人曾经花费大量时间用非编译语言编写AAA游戏。不仅如此,它极容易出错。确定性销毁在处理GPU资源等方面至关重要,而在Java中,
C。如果有的话,在哪些方面Java比C ++慢?(即数字运算,图形或周围所有图形)
我肯定会全力以赴。所有Java对象的强制引用性质意味着Java中比C ++具有更多的间接引用和引用-例如,我之前使用数组给出的示例,但也适用于所有成员对象。C ++编译器可以在恒定时间内查找成员变量,而Java运行时必须遵循另一个指针。您进行的访问越多,获取的速度就越慢,JIT对此无能为力。
在Java中,C ++几乎可以立即释放并重用一块内存,在Java中,您必须等待该内存,并且我希望那块内存不会超出缓存,并且固有地需要更多内存就意味着较低的缓存和分页性能。然后查看装箱和拆箱之类的语义。在Java中,如果要引用一个int,则必须动态分配它。与C ++语义相比,这是固有的浪费。
然后,您将遇到泛型问题。在Java中,只能通过运行时继承对通用对象进行操作。在C ++中,模板的开销实际上为零,这是Java所无法比拟的。这意味着Java中的所有通用代码本质上都比C ++中的通用代码慢。
然后您进入未定义的行为。每个人都在程序展示UB时讨厌它,并且每个人都希望它不存在。但是,UB从根本上实现了Java中永远不会存在的优化。看看这篇描述基于UB的优化的帖子。不定义行为意味着实现可以做更多的优化,并减少检查C ++中未定义但Java中定义的条件所需的代码。
从根本上讲,Java的语义表明它是一种比C ++慢的语言。
Java现在被视为编译语言还是解释语言?
它实际上不适合这些组中的任何一个。我会说托管实际上是一个单独的类别,尽管我说它绝对更像是一种解释语言,而不是编译语言。更重要的是,只有两个主要的受管系统,即JVM和CLR,当您说“受管”时,它已经足够明确了。
自早期以来,已经解决了Java的一些主要缺点?
我只知道自动装箱和拆箱。泛型解决了一些问题,但远未解决。
Java有哪些主要缺点需要解决?
它们的泛型非常非常弱。C#的泛型要强大得多-尽管当然也不是模板。确定性破坏是另一个主要缺陷。任何形式的lambda / closure也是一个主要问题-您可以忘记Java中的功能性API。当然,对于那些需要性能的领域,始终存在性能问题。