做空eth网站,友情链接适用网站,百度推广运营公司,找游戏的手游平台这篇文章是关于历史经验以及最近应用的性能优化技术的。 几年前#xff0c;我在特定的应用程序中发誓#xff0c;我不得不发现隐藏在真正聪明的工程“技术”之下的无证行为。  它是一个典型的用于发票的单片Java EE应用程序。 最好忘记确切的代码#xff0c;但是我记得开发人…   这篇文章是关于历史经验以及最近应用的性能优化技术的。 几年前我在特定的应用程序中发誓我不得不发现隐藏在真正聪明的工程“技术”之下的无证行为。   它是一个典型的用于发票的单片Java EE应用程序。 最好忘记确切的代码但是我记得开发人员已经找到了一种真正聪明的方法来控制业务流程。   流程的一部分通常是无休止的if-then-else混乱但使事情更加“令人兴奋”的是这些检查的一些随机元素被埋入了自定义java.lang.RuntimeException处理机制中。 因此您可能具有类似于以下内容的代码  if (invoice.overdue()) {if (invoice.getCustomer().isKeyCustomer())throw new InvoiceOverdueException(InvoiceOverdueException.KEY_CUSTOMER);elsedoSomething();
}
else {if (invoice.getDueAmount()  BIG_AMOUNT)if (invoice.getCustomer().isKeyCustomer())//be silentelsethrow new InvoiceExceededException(invoice.getDueAmount());
} 并非像上述那样简短易懂的块而是在整个应用程序中散布了数千行代码。   我想你可能同意我的观点这是使自己不可或缺的一种好方法。 有人会以一种疯狂的方式来理解应用程序为什么会如此。   我回想起最近的Plumbr优化任务带来的经验。 我想说我们的代码没有使用前面案例描述的异常但是不幸的是这并非完全正确。 一个特定的方法仍然在代码的常规流程中构造并抛出RuntimeException 。 由于这个特定模块的性能异常我只发现了这个孤独的反派。   通常仅在遇到意外问题时才会引发异常。 因此我们不希望每个线程每秒抛出数千个异常。 但是像我一样您可能会发现一种对异常事件使用异常的方法。   我之所以只找到罪魁祸首是因为这是特定图形遍历算法中经常使用的代码块因此从中挤出最后一毫秒至关重要。 立即删除异常处理使此代码块的完成速度提高了100倍以上。   这可能使您想知道–为什么异常处理速度很慢 最慢的部分与构造异常有关。 或者更确切地说是java.lang.Throwable的任何子类。   如果您还记得的话所有构造函数都会通过调用super来调用对超类默认构造函数的调用。 如果您未自行指定此调用则编译器会友好地将其添加到字节码本身中。 无论如何当查看java.lang.Throwable源代码时您会看到答案盯着您  public Throwable() {fillInStackTrace();}public synchronized Throwable fillInStackTrace() {if (stackTrace ! null ||backtrace ! null /* Out of protocol state */ ) {fillInStackTrace(0);stackTrace  UNASSIGNED_STACK;}return this;}private native Throwable fillInStackTrace(int dummy); 因此每次创建新的Throwable时最终都会通过本机调用填充整个堆栈跟踪。 如果您不认为这很慢请执行以下jmh微基准测试以验证创建异常的费用比构造常规对象的费用高数百倍  BenchmarkMode(Mode.AverageTime)
OutputTimeUnit(TimeUnit.NANOSECONDS)
public class NewExceptionTest {GenerateMicroBenchmarkpublic Object baseline() {return new Object();}GenerateMicroBenchmarkpublic Object exceptional() {return new RuntimeException();}
}Benchmark                          Mode Thr    Cnt  Sec         Mean   Mean error    Units
j.NewExceptionTest.baseline        avgt   1      5    5        3.275        0.029  nsec/op
j.NewExceptionTest.exceptional     avgt   1      5    5     1329.266        8.675  nsec/op 总而言之在特殊情况下名称应表示例外。 如果您开始滥用该概念那么您要么使代码不可读要么开始遭受性能问题的困扰。 至少我保证您会从中获得大量的负面因果报应。   参考 抛出异常–我们的JCG合作伙伴 Nikita Salnikov Tarnovski在Plumbr Blog博客上缓慢而丑陋 。  翻译自: https://www.javacodegeeks.com/2013/08/throwing-exceptions-slow-and-ugly.html