为我的要求提供小背景,以及到目前为止我所取得的成就: 有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.无论何种可能的方法都是静态和变量
没有费心去捕捉异常并发回,因为这些是后台任务。 (我认为这可以提高性能)
在一个查询中获取数据库值而不是多次点击。
如果我成功优化了while
循环,我想我可以节省几分钟。
感谢
答案 0 :(得分:3)
- 尽可能使方法静态 和变量
- 不要费心去捕捉异常并发回,因为这些是后台任务。 (我认为这可以提高性能)
这只会造成非常糟糕的代码风格,与性能无关。
- 在一个查询中获取数据库值而不是多次点击。
是的,这非常重要。
但总的来说,学习如何使用分析器来查看代码实际花费时间的位置,以便您可以改进这些部分,而不是根据传闻进行随机“优化”,就像您现在所做的那样。 / p>
答案 1 :(得分:1)
使用静态&只有当你没有使用体面的JIT编译器时,final才能提高性能。由于大多数JRE已经使用了良好的JIT编译器,因此可以忽略最终和静态性能。
更好地检查锁定和同步方式。锁定问题的一个很好的指标是应用程序的CPU使用率。如果它应该很难工作,那么可能会有锁或db-queries阻塞你的应用程序。
也许你可以使用Copy-On-Write或ReadWriteLocks等技术。
另请查看concurrent和atomic个软件包,了解如何改进或消除锁定的一些想法。
如果有一个CPU核心负载较高而其他CPU闲置,请尝试并行处理。 ExecutorService在这里可能会有所帮助。
答案 2 :(得分:1)
在知道需要修理的内容之前,请不要修理任何内容。迈克尔是对的 - 个人资料 - 但是I prefer this method。
了解时间尺度。当人们优化while
循环时,它们的工作时间为纳秒级。执行数据库查询时,它处于毫秒级别。当您发送电子邮件并等待I / O完成时,您正在说几秒钟。如果你有几秒钟的延迟,做一些只能节省毫秒或几纳秒的事情会让你对结果感到失望。 **
因此,找出(不要猜测)导致大部分延迟的原因,并从那里开始工作。
**为了了解时间尺度,1秒内光子可以在大部分时间到达月球;在1毫秒内,它可以穿越一个中等大小的国家,在1纳秒内,它可以穿过你的脚。
答案 3 :(得分:1)
假设您先对应用程序进行了分析,并发现大部分延迟不在您的程序中,而在其他地方,例如网络/邮件服务器......
您可以创建固定大小的线程池,例如2-4线程。并为您在当前线程中发送的每封邮件添加任务。
答案 4 :(得分:1)
检查您的代码,删除明显缓慢的构造。
垃圾收集器是你的朋友,但它会向你收取很高的价格。你必须尽力摆脱gc。首选由原始类型组成的简单数据结构。
例外是另一个非常方便的事情,它会向你收取很高的价格。 它们非常昂贵,因为每次抛出异常时,都必须创建并填充堆栈跟踪。想象一下,由于缺乏资金,平衡转移操作在1%的情况下失败。即使故障率相对较低,性能也可能受到严重影响。请参阅this benchmark。
检查您的逻辑和算法。尝试并行执行操作。
尽可能使用批量数据移动。
使用批量数据库操作并始终使用PreparedStatements。
仅在此之后使用分析技术。
分析代码应该是最后的手段。 如果你已经完成了正确的作业,那么分析只会略微有所贡献。