1. 内存使用率。当CPU性能增加时访问RAM就会变得相对缓慢,因此内存使用率在实际运用中非常重要。这一点,Java则显得相对弱一点:a.每个对象至少占用8个字节;b.无法使用堆栈分配对象;C.常用库存迫使形成一个对象。此外,Java对象数组能真正引用数组,因此不能连续分配,这会迫使性能缓存损坏。
2. 垃圾回收。这是Java常见的一种诟病。C++有着明确、清晰的内存管理,你可以严格控制分配内存和释放内存的过程。也就说,所有大量的块可以在分配前进行合并,而long-lived memory在此过程中只需要付出最小的代价。然而,我曾遇到过C++性能问题:内存碎片化。垃圾回收机制不断压缩内存使用使其形成一个连续的模块——这的确能帮助性能避免内存碎片化。倘若在C++里长期运行应用程序,内存会严重分裂从而会影响时间分配和性能缓存。尤其是在进行大量的内存分配下,波动会很明显。
3. 语言规范。Java语言规范在Java程序执行顺序上更为具体。例如,表达式总是以从左到右的方式执行。而在C++中实现的方式则更加灵活,导致项目很难调试,但却给编译器带来更多的自由空间。就我个人而言,我认为Java语言规范确实是以正确的方式发展,至少这样确保了软件质量(但未能给你带来惊喜),因此在这一方面我很赞同Java。
4. 执行模式。使用JIT(Just-In-Time)虚拟机编译器(Java)与静态的编译模式(C++)相比的确有优势。特别是虚拟机可以根据程序当前的工作负荷进行优化。与其相反,静态编译模式则预测未来工作负荷的时间以便进行集中优化。如此一来,就会导致一些问题出现,如果普遍使用某些性能优化(inlining内部的)就会产生一些负面影响。为了解决这个问题,现代版C++编译器开始支持PGO(Profile Guided Optimization)优化程序,有了它就可帮助缓解此问题发生。然而,长期运行的程序有着不同的和不可预测的负荷行为,JIT(理论上)具备一定的优势。尽管Web应用程序可能会适应于某个区域,但目前尚未得知,当前JIT是如何适应不断变化的负载区域?(当他们无意义时,会撤销优化吗?)
我认为性能仍然是语言设计的一个关键问题。很多人说“机器运行非常快”或者说“这是一个非常智能的编译器”……实际上,这些编译器从未因满足现状而裹足不前。打个比方,几年前只有几万点击率,而今Web应用必须每天扩展数以万计的点击率(或者更多),而且在未来我们还希望有更多的点击量。
内存使用是一个最基本的性能瓶颈,这不禁让我开始质疑纯面向对象语言的未来。当今有很多语言似乎很流行(比如,Scala,Ruby等等)。令人担忧的是,只是不知道这些语言能否满足未来性能的需求。