如何提高每n'分钟运行一次的循环的性能

时间:2010-06-07 13:23:25

标签: java performance

为我的要求提供小背景,以及到目前为止我所取得的成就: 有18个Scheduler任务定期运行(最少30分钟),需要输入近5000名符合条件的员工进入静态迭代方法,并为该员工和邮件生成邮件内容。平均任务需要大约9分钟乘以18将大约162分钟,同时将有下一个任务将在队列中(我假设)。 所以我的计划类似于下面的循环

try {                       
        // Handle Arraylist of alerts eligible employees
        Iterator employee = empIDs.iterator();          
        while (employee.hasNext()) {                

            ScheduledImplementation.getInstance().sendAlertInfoToEmpForGivenAlertType((Long)employee.next(), configType,schedType);                             
        }
    } catch (Exception vEx)
    {
        _log.error("Exception Caught During sending " + configType + " messages:" + configType, vEx);
    }

由于我知道有多少员工会使用我的方法,因此我将while循环分为两个,并一次对两个或三个员工同时执行操作。这可能吗。或者还有其他方法可以改善性能。 到目前为止我实施的一些事情

1.无论何种可能的方法都是静态和变量

  1. 没有费心去捕捉异常并发回,因为这些是后台任务。 (我认为这可以提高性能)

  2. 在一个查询中获取数据库值而不是多次点击。

  3. 如果我成功优化了while循环,我想我可以节省几分钟。 感谢

5 个答案:

答案 0 :(得分:3)

  
      
  • 尽可能使方法静态   和变量
  •   
  • 不要费心去捕捉异常并发回,因为这些是后台任务。 (我认为这可以提高性能)
  •   

这只会造成非常糟糕的代码风格,与性能无关。

  
      
  • 在一个查询中获取数据库值而不是多次点击。
  •   

是的,这非常重要。

但总的来说,学习如何使用分析器来查看代码实际花费时间的位置,以便您可以改进这些部分,而不是根据传闻进行随机“优化”,就像您现在所做的那样。 / p>

答案 1 :(得分:1)

使用静态&只有当你没有使用体面的JIT编译器时,final才能提高性能。由于大多数JRE已经使用了良好的JIT编译器,因此可以忽略最终和静态性能。

更好地检查锁定和同步方式。锁定问题的一个很好的指标是应用程序的CPU使用率。如果它应该很难工作,那么可能会有锁或db-queries阻塞你的应用程序。

也许你可以使用Copy-On-Write或ReadWriteLocks等技术。

另请查看concurrentatomic个软件包,了解如何改进或消除锁定的一些想法。

如果有一个CPU核心负载较高而其他CPU闲置,请尝试并行处理。 ExecutorService在这里可能会有所帮助。

答案 2 :(得分:1)

在知道需要修理的内容之前,请不要修理任何内容。迈克尔是对的 - 个人资料 - 但是I prefer this method

了解时间尺度。当人们优化while循环时,它们的工作时间为纳秒级。执行数据库查询时,它处于毫秒级别。当您发送电子邮件并等待I / O完成时,您正在说几秒钟。如果你有几秒钟的延迟,做一些只能节省毫秒或几纳秒的事情会让你对结果感到失望。 **

因此,找出(不要猜测)导致大部分延迟的原因,并从那里开始工作。

**为了了解时间尺度,1秒内光子可以在大部分时间到达月球;在1毫秒内,它可以穿越一个中等大小的国家,在1纳秒内,它可以穿过你的脚。

答案 3 :(得分:1)

假设您先对应用程序进行了分析,并发现大部分延迟不在您的程序中,而在其他地方,例如网络/邮件服务器......

您可以创建固定大小的线程池,例如2-4线程。并为您在当前线程中发送的每封邮件添加任务。

答案 4 :(得分:1)

检查您的代码,删除明显缓慢的构造。

  1. 垃圾收集器是你的朋友,但它会向你收取很高的价格。你必须尽力摆脱gc。首选由原始类型组成的简单数据结构。

  2. 例外是另一个非常方便的事情,它会向你收取很高的价格。 它们非常昂贵,因为每次抛出异常时,都必须创建并填充堆栈跟踪。想象一下,由于缺乏资金,平衡转移操作在1%的情况下失败。即使故障率相对较低,性能也可能受到严重影响。请参阅this benchmark

  3. 检查您的逻辑和算法。尝试并行执行操作。

  4. 尽可能使用批量数据移动。

  5. 使用批量数据库操作并始终使用PreparedStatements。

  6. 仅在此之后使用分析技术。

  7. 分析代码应该是最后的手段。 如果你已经完成了正确的作业,那么分析只会略微有所贡献。