Hashmap循环性能问题

时间:2017-03-09 17:13:22

标签: java performance loops

这段代码存在性能问题,我要求修复它。无法修改doTransaction()和printTransactions()方法。

我尝试在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);
    }
}

2 个答案:

答案 0 :(得分:1)

正如您所说,如果您提出的doTransaction()实施必须被调用1000次,并且假设每次调用至少需要10秒,则消耗的总时间至少为10000秒,这几乎是三秒小时。大幅减少消耗时间的唯一方法是并行执行许多doTransaction()次呼叫。要将10000秒降低到1200秒以下,您需要至少9倍的并发性。如果这是您期望采用的方法,那么原始processTransactions()方法的结构建议10倍并发。

话虽如此,这是一个完全不切实际的模型。在现实世界中,您不能指望并行化的线性加速,并且无论如何,您可以自由并行化,而不考虑工作负载的细节。它可以在这里工作,因为doTransaction()实际上并没有执行任何工作,但我没有看到你实际应该带走的实用课程。

无论如何,不​​要指望我提供任何实际代码。我 - 我们很乐意在你的家庭作业上偶尔给你帮助和指导,但我们不会为你做。

答案 1 :(得分:0)

循环是我看到的最重要的事情,但你需要它;你有没有为每个循环尝试一个?,也许尝试使用AddExact(如果你可以使用整数而不是double)方法,你的添加结果。如果您有大量的事务,请尝试在for循环中移动它们,并确保从cmd而不是ide

测试程序