当我读到有关C#或Java等JITted语言的性能时,作者通常会说它们理论上应该/可以胜过许多本机编译的应用程序.理论上,本机应用程序通常只是为处理器系列(如x86)编译,因此编译器无法进行某些优化,因为它们可能并非真正在所有处理器上进行优化.另一方面,CLR可以在JIT过程中进行特定于处理器的优化.
有谁知道微软(或Mono)的CLR在JIT过程中是否实际执行特定于处理器的优化?如果是这样,有什么样的优化?
我们正在使用Python 制作一些kNN和SVD实现.其他人选择了Java.我们的执行时间非常不同.我使用cProfile来查看我在哪里犯错但实际上一切都很好.是的,我numpy也用.但我想问一个简单的问题.
total = 0.0
for i in range(9999): # xrange is slower according
for j in range(1, 9999): #to my test but more memory-friendly.
total += (i / j)
print total
Run Code Online (Sandbox Code Playgroud)
这段代码在我的电脑上占用了31.40秒.
此代码的Java版本在同一台计算机上占用1秒或更短时间.我想,类型检查是这段代码的主要问题.但我应该为我的项目做很多这样的操作,我认为9999*9999不是那么大的数字.
我想我犯了错误,因为我知道Python被很多科学项目所使用.但是为什么这段代码这么慢,我怎么能处理比这更大的问题呢?
我应该使用JIT编译器Psyco吗?
我还说这个循环问题只是一个例子.代码并不像这样简单,可能很难将改进/代码示例付诸实践.
另一个问题是,我可以实现大量的数据挖掘和机器学习算法与numpy和scipy,如果我正确地使用它?
他们俩几乎都做同样的事情.确定方法很热并编译它而不是解释.使用OSR,您只需在编译后立即转移到编译版本,这与JIT不同,后者在第二次调用方法时调用编译代码.
除此之外,还有其他差异吗?
为什么要注释这个for循环的前两行,并在42%的加速时取消注释第三个结果?
int count = 0;
for (uint i = 0; i < 1000000000; ++i) {
var isMultipleOf16 = i % 16 == 0;
count += isMultipleOf16 ? 1 : 0;
//count += i % 16 == 0 ? 1 : 0;
}
Run Code Online (Sandbox Code Playgroud)
在时序背后是非常不同的汇编代码:循环中的13对7指令.该平台是运行.NET 4.0 x64的Windows 7.启用了代码优化,测试应用程序在VS2010之外运行.[ 更新: Repro项目,对验证项目设置很有用.]
消除中间布尔值是一个基本的优化,是我1980年代龙书中最简单的一个.在生成CIL或JITing x64机器代码时,如何不应用优化?
有没有"真正的编译器,我希望你优化这段代码,请"切换?虽然我同情过早优化类似于对金钱的热爱的情绪,但我可以看到试图描述一个复杂算法的挫败感,这个算法在整个惯例中分散.你可以通过热点工作,但没有暗示更广泛的温暖区域可以通过手动调整我们通常认为理所当然的编译器来大大改善.我当然希望我在这里遗漏一些东西.
更新: x86也会出现速度差异,但取决于方法即时编译的顺序.请参阅为什么JIT订单会影响性能?
汇编代码(根据要求):
var isMultipleOf16 = i % 16 == 0;
00000037 mov eax,edx
00000039 and eax,0Fh
0000003c xor ecx,ecx …Run Code Online (Sandbox Code Playgroud) JIT编译器和CLR有什么区别?如果您将代码编译为il并且CLR运行该代码,那么JIT正在做什么?JIT编译如何通过向CLR添加泛型来改变?
在最近关于如何优化某些代码的讨论中,我被告知将代码分解为许多小方法可以显着提高性能,因为JIT编译器不喜欢优化大型方法.
我不确定这一点,因为看起来JIT编译器本身应该能够识别自包含的代码段,而不管它们是否在他们自己的方法中.
任何人都可以确认或驳斥这一说法吗?
我找不到JIT和口译员之间的区别.
Jit是口译员和编译器的中介.在运行时,它将字节代码转换为机器代码(JVM或实际机器?)下次,它从缓存中运行并运行Am i对吗?
解释器将直接执行字节码而不将其转换为机器代码.是对的吗?
我们电脑中真正的处理器如何理解指令.
请清除我的疑虑.
运行Java 1.6(1.6.0_03-b05)应用程序时,我添加了-XX:+PrintCompilation标志.在某些方法的输出中,特别是我知道的一些方法被大量调用,我看到了文本made not entrant和made zombie.
这些是什么意思?最好的猜测是,在重新编译该方法或具有更高优化的依赖项之前,它是一个反编译步骤.真的吗?为什么"僵尸"和"参赛者"?
例如,其中一些行之间有相当长的时间:
[... near the beginning]
42 jsr166y.LinkedTransferQueue::xfer (294 bytes)
[... much later]
42 made not entrant jsr166y.LinkedTransferQueue::xfer (294 bytes)
--- n sun.misc.Unsafe::compareAndSwapObject
170 jsr166y.LinkedTransferQueue::xfer (294 bytes)
170 made not entrant jsr166y.LinkedTransferQueue::xfer (294 bytes)
4% jsr166y.LinkedTransferQueue::xfer @ 29 (294 bytes)
171 jsr166y.LinkedTransferQueue::xfer (294 bytes)
[... even later]
42 made zombie jsr166y.LinkedTransferQueue::xfer (294 bytes)
170 made zombie jsr166y.LinkedTransferQueue::xfer (294 bytes)
171 made not entrant jsr166y.LinkedTransferQueue::xfer (294 bytes)
172 jsr166y.LinkedTransferQueue::xfer (294 …Run Code Online (Sandbox Code Playgroud) 是否存在JIT编译器比其他编译器(如C++)更快的情况?
您认为将来JIT编译器只会看到次要的优化,功能但是会遵循类似的性能,还是会有突破性的优势使其无限优于其他编译器?
看起来多核心范式有一些希望,但它不是普遍的魔力.
任何见解?
有(相对)众所周知的Perl公理,"只有perl可以解析Perl." 我想知道,Perl 6会保持这种情况吗?
扩展讨论......考虑到PyPy最近的更新,我想到了这个问题.Perl的独特解析能否阻止它进行类似的工作?在Perl代码(PPI?)的受限制的静态视图中有多大价值?Perl 6可以有一个JIT编译器吗?*
*我不确定这些概念是否相关.是吗?
jit ×10
c# ×4
java ×4
.net ×3
clr ×2
optimization ×2
performance ×2
c++ ×1
jvm ×1
jvm-hotspot ×1
parsing ×1
perl ×1
perl6 ×1
python ×1
raku ×1