我最近听到很多人说,JIT编译产生的代码非常快,甚至比任何静态编译器都要快。当涉及到C++ STL风格的模板代码时,我觉得这很难相信,但是这些人(通常来自C#/Java背景)坚持认为情况确实如此。
因此,我的问题是:什么类型的优化可以在运行时进行,而不能在编译时进行?
编辑:澄清:我更感兴趣的是那些不可能静态做的事情,而不是任何一个行业的典型案例。
发布于 2018-01-30 02:53:54
JIT编译器可以度量条件跳转的可能性,并相应地调整发出的代码。静态编译器也可以这样做,但不是自动的;它需要程序员的提示。
显然,这只是众多因素中的一个因素,但它确实表明,在适当的条件下,JIT可以更快。
发布于 2018-01-30 01:36:04
你可以在运行时做的事情
还有其他我从清单上遗漏的东西
这会使事情总是快10倍吗,不。但它确实为编译时无法获得的优化提供了机会(对于分布广泛的代码;显然,如果您知道它只在3种不同的硬件配置上,那么您可以定制构建等等)。
发布于 2018-01-30 01:28:50
与上述说法相反的是:
尽管如此,即使使用多核优化也不能使使用JIT编译器变得有用,因为程序的安装程序可以检查可用的核数,并安装适合该计算机核数的程序的适当版本。
我不认为JIT编译比静态编译有更好的性能。始终可以创建多个版本的代码,每个版本都是针对特定设备进行优化的。我认为唯一能导致JIT代码速度更快的优化类型是当您接收到输入时,无论您使用什么代码来处理它,都可以对最常见的情况( JIT编译器可能会发现的情况)使代码更快地进行优化,但对于较少见的情况则更慢。即使这样,您也可以执行该优化(但是,静态编译器将无法执行此优化)。
例如,假设您可以对一个导致值1-100的错误的数学算法执行优化,但是所有较高的数字都可以用于此优化。您注意到,可以很容易地预先计算值1-100,因此您可以这样做:
switch(num) {
case 0: {
//code
}
//...until case 100
}
//main calculation code然而,这是低效的(假设开关语句没有编译到跳转表中),因为在没有计算机帮助的情况下,很少输入0-100,因为它们是在精神上找到的。JIT可能会发现这更有效(当看到范围为0-100的值很少被输入时):
if(num < 101) {
switch(num) {
/...same as other code above
}
}
//main calculation code在这个版本的代码中,只有一个if被执行,如果是最常见的情况,而不是在非常罕见的情况下平均50个ifs (如果开关语句是作为一系列ifs实现的)。
https://stackoverflow.com/questions/48512433
复制相似问题