2017-03-09 109 views
-2

這段代碼有一個性能問題,我要求修復它。 doTransaction()和printTransactions()方法不能被修改。Hashmap循環性能問題

我試圖在processTransactions()中做一些更改,但它沒有成功。任何建議都將被佔用。

import java.util.EnumMap; 
import java.util.HashMap; 
import java.util.Map; 
public class TransactionProcessor { 
    /** The number of transactions */ 
    private static final int NUM_TRANSACTIONS = 1000; 
    /** The status of a transaction */ 
    private static enum Status { 
     RUNNING, 
     OK, 
     FAILURE 
    } 
    /** The status of transactions */ 
    private HashMap <Integer, Status> transactionStatus = new HashMap<>(); 
    /** 
    * Perform the complex transaction. This method must be called by the  exercise and cannot be changed 
    * @param input the input of the transaction 
    * @return the output of the transaction 
    */ 
    final protected double doTransaction(double input) throws InterruptedException { 
     // --- You cannot modify this method --- 
     Thread.sleep(10000); 
     return input * 100; 
    } 
    /** 
    * Print the number of transactions. This method must be called by the exercise and cannot be changed 
    * @param transactions an object describing the transaction status 
    */ 
    final protected void printTransactions(Map < ?, Status > transactions) { 
     // --- You cannot modify this method --- 
     EnumMap < Status, 
     Integer > counts = new EnumMap<>(Status.class); 
     for (Status s: Status.values()) { 
      counts.put(s, 0); 
     } 
     for (Status s: transactions.values()) { 
      counts.put(s, counts.get(s) + 1); 
     } 
     System.out.printf("- %d Ok transactions, %d Running transactions, " + "%d Failed transactions. Completed percentage: %s%%\n", counts.get(Status.OK), counts.get(Status.RUNNING), counts.get(Status.FAILURE), (counts.get(Status.OK) + counts.get(Status.FAILURE)) * 100.0/NUM_TRANSACTIONS); 
    } 
    /** 
    * Process all transactions 
    * @return the output of all transactions 
    */ 
    public double processTransactions() { 
     double result = 0.0; 
     for (int i = 0; i < NUM_TRANSACTIONS; i++) { 
      try { 
       transactionStatus.put(i, Status.RUNNING); 
       result += doTransaction(i); 
       transactionStatus.put(i, Status.OK); 
       printTransactions(transactionStatus); 
      } catch(InterruptedException ex) { 
       System.out.println("Transaction failed"); 
       transactionStatus.put(i, Status.FAILURE); 
      } 
     } 
     return result; 
    } 
    /** 
    * Main method. Display the result and execution time. 
    * @param args (not used) 
    */ 
    public static void main(String[] args) { 
     long startTime = System.currentTimeMillis(); 
     TransactionProcessor tp = new TransactionProcessor(); 
     double result = tp.processTransactions(); 
     System.out.printf("The result is: %f . " + "Elapsed time: %s seconds\n", result, (System.currentTimeMillis() - startTime)/1000.0); 
    } 
} 
+6

我不明白你可以觀察到什麼性能問題,它不會被'doTransaction()'中的十秒鐘睡眠絕對*淹沒*。爲了減少流逝的時間,調用'doTransaction()'次數更少。 –

+0

如果10秒睡眠甚至可以遠程代表實際過程,那麼當前沒有任何「processTransactions()」會移動性能指針。不是說,processTransactions()似乎本身無論如何都是無效的。 –

+0

[Java HashMap性能優化/替代]的可能重複(http://stackoverflow.com/questions/1757363/java-hashmap-performance-optimization-alternative) –

回答

0

for循環是我看到的最大的東西,但你需要它;你是否嘗試了每個循環?,也許嘗試使用AddExact(如果可以使用整數而不是double)方法添加結果。如果您的交易數量非常大,請嘗試將其移動到for循環中,並確保您正在從cmd而不是ide測試程序

+0

使用INT使它更好一點,但它應該快6倍,所以我不認爲這將是解決方案。 –

+0

NUM_TRANSACTIONS的值是多少? – BlooB

1

如果您像所說的那樣執行您提供的doTransaction()必須被稱爲1000次,並且鑑於每次通話至少需要10秒,所消耗的總時間至少爲10000秒,這接近3個小時。大幅減少耗費時間的唯一方法是並行執行多個調用doTransaction()。要將10000秒下降到1200秒以下,您至少需要9倍的併發性。如果這是您期望採用的方法,那麼原始processTransactions()方法的結構表明10倍併發性。

就這樣說,這是一個完全不現實的模型。在現實世界中,你不能期望線程從並行化加速,無論如何,很少情況下你可以自由並行,而不考慮工作負載的細節。它會在這裏工作,因爲doTransaction()實際上並沒有執行任何工作,但我沒有看到你實際上應該拿走什麼有用的教訓。

無論如何,不​​要指望我提供任何實際的代碼。我 - 我們 - 很樂意爲您提供偶爾的幫助和指導,但我們不會爲您做。