2017-03-09 73 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()实际上并没有执行任何工作,但我没有看到你实际上应该拿走什么有用的教训。

无论如何,不​​要指望我提供任何实际的代码。我 - 我们 - 很乐意为您提供偶尔的帮助和指导,但我们不会为您做。