代码之家  ›  专栏  ›  技术社区  ›  GustyWind

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

  •  0
  • GustyWind  · 技术社区  · 15 年前

    对我的要求和迄今为止我所完成的工作提供了一点背景: 有18个调度程序任务定期运行(至少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. 在一个查询中获取db值,而不是多次命中。

    如果我成功地优化了 while 我想我可以节省几分钟。 谢谢

    5 回复  |  直到 14 年前
        1
  •  3
  •   Justin Peel    15 年前
    • 尽可能使方法静态化 还有变量
    • 不要费心捕捉异常并返回,因为这些是后台任务。(我认为这会提高性能)

    这只会导致非常糟糕的代码样式,与性能无关。

    • 在一个查询中获取db值,而不是多次命中。

    是的,这是非常必要的。

    但一般来说,学习如何使用分析器来查看代码实际花费的时间,以便改进这些部分,而不是像现在这样根据传闻进行随机的“优化”。

        2
  •  1
  •   Hardcoded    15 年前

    只有当您不使用合适的JIT编译器时,才使用static&final提高性能。由于大多数JRE已经在使用一个好的JIT编译器,所以可以忽略final和static来提高性能。

    最好检查您的锁定和同步风格。锁定问题的一个好指标是应用程序的CPU使用情况。如果它是低的,当它应该是努力工作时,可能有锁或数据库查询阻塞您的应用程序。

    也许你可以使用一些技术,比如写时复制或者 ReadWriteLocks .

    同时查看 concurrent atomic 包中有一些关于如何改进或消除锁定的想法。

    如果有一个CPU内核负载很高,而其他的则在空闲,那么尝试并行处理。安 ExecutorService 可能会有帮助。

        3
  •  1
  •   Community CDub    8 年前

    在你知道需要修复什么之前,请不要修复任何东西。迈克尔是对的-侧面-但是 I prefer this method .

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

    所以,找出(不要猜)造成大多数延迟的原因,然后从那里开始工作。

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

        4
  •  1
  •   Peter Lawrey    15 年前

    假设您首先分析了您的应用程序,发现大多数延迟不在您的程序中,而是在其他地方,例如网络/邮件服务器…

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

        5
  •  1
  •   Richard Gomes    14 年前

    检查您的代码,删除故意缓慢的结构。

    1. 垃圾收集者是你的朋友,但收费很高。你必须尽最大努力摆脱GC。更喜欢由基元类型构成的简单数据结构。

    2. 例外是另一个非常方便的事情,它收费很高。 它们非常昂贵,因为每次抛出异常时,都必须创建和填充堆栈跟踪。设想一个余额转移操作在1%的情况下由于资金不足而失败。即使故障率相对较低,性能也可能受到严重影响。见 this benchmark .

    3. 回顾你的逻辑和算法。尝试并行执行操作。

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

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

    6. 之后才使用分析技术。

    分析代码应该是最后的手段。 如果你做了正确的家庭作业,那么分析只会有轻微的贡献。