Java中已投入系统变得异常缓慢_Java异常有多慢?

这取决于异常是如何实现的。最简单的方法是使用setjmp和long jmp。这意味着CPU的所有寄存器都被写入堆栈(这已经花费了一段时间),并且可能需要创建一些其他数据.所有这些都已经发生在try语句中。抛出语句需要展开堆栈并恢复所有寄存器(以及VM中可能的其他值)的值。所以,尝试和抛出是同样慢的,这是相当慢的,但是如果没有抛出异常,退出try块在大多数情况下都不需要任何时间(因为所有东西都放在堆栈上,如果存在方法就会自动清理)。

Sun和其他人认识到,这可能不是最优的,当然,VM会随着时间的推移变得越来越快。还有另一种实现异常的方法,它可以使try自身快速运行(实际上,通常不会发生任何情况-当类被VM加载时,需要发生的所有事情都已经完成了),而且抛出的速度也没有那么慢。我不知道哪个JVM使用这种新的更好的技术.。

但是您是用Java编写的吗?所以以后您的代码只运行在一个特定系统上的一个JVM上吗?因为如果它可能运行在任何其他平台或任何其他JVM版本(可能是任何其他供应商),那么谁说他们也使用快速实现呢?快的比慢的复杂,不容易在所有的系统上实现。你想随身携带吗?那么,不要依赖异常是快速的。

在尝试块中所做的事情也有很大的不同。如果您打开一个try块,并且从未从这个try块中调用任何方法,那么try块将是超快的,因为JIT可以将抛出作为一个简单的Goto。它不需要保存堆栈状态,也不需要在抛出异常时解除堆栈(只需要跳转到CATCH处理程序)。然而,这不是你通常做的。通常,您打开一个try块,然后调用一个可能引发异常的方法,对吗?即使您只是在您的方法中使用try块,这将是什么样的方法,它不会调用任何其他方法?它能计算一个数字吗?那你为什么需要例外呢?有更优雅的方法来调节程序流。除了简单的数学之外,几乎所有其他的方法都必须调用外部方法,这已经破坏了本地try块的优势。

请参阅下列测试代码:public class Test {

int value;

public int getValue() {

return value;

}

public void reset() {

value = 0;

}

// Calculates without exception

public void method1(int i) {

value = ((value + i) / i) <

// Will never be true

if ((i & 0xFFFFFFF) == 1000000000) {

System.out.println("You'll never see this!");

}

}

// Could in theory throw one, but never will

public void method2(int i) throws Exception {

value = ((value + i) / i) <

// Will never be true

if ((i & 0xFFFFFFF) == 1000000000) {

throw new Exception();

}

}

// This one will regularly throw one

public void method3(int i) throws Exception {

value = ((value + i) / i) <

// i & 1 is equally fast to calculate as i & 0xFFFFFFF; it is both

// an AND operation between two integers. The size of the number plays

// no role. AND on 32 BIT always ANDs all 32 bits

if ((i & 0x1) == 1) {

throw new Exception();

}

}

public static void main(String[] args) {

int i;

long l;

Test t = new Test();

l = System.currentTimeMillis();

t.reset();

for (i = 1; i 

t.method1(i);

}

l = System.currentTimeMillis() - l;

System.out.println(

"method1 took " + l + " ms, result was " + t.getValue()

);

l = System.currentTimeMillis();

t.reset();

for (i = 1; i 

try {

t.method2(i);

} catch (Exception e) {

System.out.println("You'll never see this!");

}

}

l = System.currentTimeMillis() - l;

System.out.println(

"method2 took " + l + " ms, result was " + t.getValue()

);

l = System.currentTimeMillis();

t.reset();

for (i = 1; i 

try {

t.method3(i);

} catch (Exception e) {

// Do nothing here, as we will get here

}

}

l = System.currentTimeMillis() - l;

System.out.println(

"method3 took " + l + " ms, result was " + t.getValue()

);

}}

结果:method1 took 972 ms, result was 2method2 took 1003 ms, result was 2method3 took 66716 ms, result was 2

TRY块的减速太小,不能排除诸如后台进程之类的混淆因素。但是,捕获块杀死了一切,使它慢了66倍!

正如我说过的,如果将TRY/CATCH并将所有抛入相同的方法(方法3)中,结果不会那么糟糕,但是这是一个我不会依赖的特殊的JIT优化。即使在使用此优化时,抛出仍然相当缓慢。所以我不知道你在做什么,但是肯定有比尝试/捕捉/扔更好的方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值