2010-06-07 111 views
0

爲我的要求提供小背景以及迄今爲止完成的工作: 有18個計劃任務以固定間隔(至少30分鐘)運行將近5000名符合條件的員工輸入一個靜態方法進行迭代,併爲該員工和郵件生成郵件內容。一個平均的任務需要大約9分鐘乘以18將大約162分鐘,同時會有下一個任務將在隊列中(我假設)。 所以我的計劃是像下面的循環如何提高每運行n分鐘的循環的性能

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.Wherever可能由靜態方法我已經實現的東西和變數太多

  • 沒有刻意去捕捉異常併發送回,因爲這些是後臺任務。 (並且我認爲這會提高性能)

  • 獲取一個查詢中的DB值而不是多個匹配。

  • 如果我成功優化了while循環,我想我可以節省幾分鐘。 感謝

    +0

    當您執行sendAlertInfoToEmpForGivenAlertType時,發送郵件時是否阻止? EG:您是否等到在您返回並處理下一條記錄之前實際發送郵件? – Paul 2010-06-07 13:34:16

    +0

    沒有。這不是線程安全的 – GustyWind 2010-06-07 13:39:50

    回答

    3
    • 儘可能化妝方法靜態 和變量太多
    • 不要刻意去捕捉異常併發送回,因爲這是後臺任務。 (我想這可以提高性能)

    ,只是讓了非常糟糕的代碼風格,無關的性能。

    • 在一個查詢中獲取DB值而不是多個匹配。

    是的,這可能是非常重要的。

    但總的來說,學習如何使用分析器來查看代碼實際花費的時間,以便您可以改進這些部分,而不是像傳聞中那樣進行隨機「優化」,就像您現在正在做的那樣。

    +0

    對於(1)使用私有和靜態方法以及最終類來鼓勵編譯器進行內聯處理 - 來自以下鏈接http://www.javaperformancetuning.com/tips/rawtips.shtml 思想這會提高性能。 (2)我需要通過一個例外,當用戶應該真的知道什麼是失敗,但因爲這是我沒有做的後臺任務。 – GustyWind 2010-06-07 13:38:35

    +0

    @GustlyWind:(1)最初來自1998年的最後更新頁面.JIT編譯器自那時起已經獲得了很多* * *更多。 Java的大多數性能建議相似,過時並且通常是有害的。 (2)是否捕獲異常(以及哪裏)與性能完全無關,而是與代碼的正確性和可維護性有關。 – 2010-06-07 14:13:23

    1

    使用靜態&只有當您沒有使用體面的JIT編譯器時,final纔會提高性能。由於大多數JRE已經在使用良好的JIT編譯器,因此您可以忽略最終和靜態的性能。

    更好地檢查你的鎖定和同步風格。鎖定問題的一個很好的指標是應用程序的CPU使用率。如果它應該很勤奮,那麼可能會有鎖或db查詢阻止你的應用程序。

    也許你可以使用寫複製或ReadWriteLocks等技術。

    另外檢查了concurrentatomic包的一些想法如何改善或消除鎖定。

    如果有一個高負載的CPU核心,而其他CPU空閒,嘗試並行處理。 ExecutorService在這裏可能會有所幫助。

    1

    請不要修復任何問題,直到您知道需要修復的問題。邁克爾是正確的 - 簡介 - 但I prefer this method

    瞭解時間尺度。當人們優化while循環時,他們正在工作在納秒級別。當您執行數據庫查詢時,它處於毫秒級別。當您發送電子郵件並等待I/O完成時,您正在說幾秒鐘。如果你的延遲時間爲幾秒,做一些只能保存毫秒或納秒的東西會讓你對結果感到失望。 **

    因此,找出(不要猜測)什麼導致了大部分的延遲,並從那裏開始工作。

    **爲了給出時間尺度的感覺,在1秒內光子可以傳播到月球的大部分路徑;在1毫秒內它可以穿過一箇中等大小的國家,在1納秒內它可以穿過你的腳。

    1

    假設您首先對您的應用程序進行了簡介,並發現大部分延遲不在您的程序中,而是在其他地方,例如網絡/郵件服務器....

    您可以創建一個固定大小的線程池,例如2-4線程。併爲您在當前線程中發送的每封郵件添加一項任務。

    1

    查看您的代碼,刪除明顯緩慢的構造。

    1. 垃圾收集器是你的朋友,但它收取你非常高的價格。你必須儘可能地去除gc。優先考慮由原始類型組成的簡單數據結構。

    2. 例外是另一個非常方便的事情,它會收取非常高的價格。 它們非常昂貴,因爲每次引發異常時,都必須創建並填充堆棧跟蹤。想象一下,由於缺乏資金,平衡轉移操作在1%的案例中失敗。即使這種相對較少的失敗率,性能可能會受到嚴重影響。見this benchmark

    3. 檢查你的邏輯和算法。嘗試並行執行操作。

    4. 如果可能,請使用批量數據移動。

    5. 使用批量數據庫操作並始終使用PreparedStatements。

    6. 只有在那之後使用分析技術。

    分析代碼應該是最後的手段。 如果你已經正確完成了功課,分析只會略有貢獻。