我有一个股票代码,然后从数据库我得到一个分析的股票(股票)的详细信息。在循环中,我将分析的滴答器的细节与其他代码的细节进行比较,计算相关性,然后将其添加到treeSet中。
这是我第一次使用多线程,我希望在更短的时间内执行该方法。我不确定这个解决方案。你能检查一下我的代码并判断一下吗?
这是我的服务:
@Service public class StatisticService{
@Inject
private StockDetailsRepository stockDetailsRepository;
@Inject
private StockRepository stockRepository;
private List<GpwStockTicker> tickersWithOutOneAnalysed;
private TreeSet<StockStatistic> correlationTreeSet;
private double [] closePricesAnalysed;
private int size;
private PearsonsCorrelation pearsonsCorrelation;
public TreeSet<StockStatistic> computePearsonCorrelation(Stock stock, int size) {
this.size = size;
long start = System.currentTimeMillis();
correlationTreeSet = new TreeSet<>();
pearsonsCorrelation = new PearsonsCorrelation();
GpwStockTicker mainTicker = stock.getTicker();
List<StockDetails> stockDetailsAnalysed = getContent(mainTicker, size);
closePricesAnalysed = getClosePrices(stockDetailsAnalysed);
EnumSet<GpwStockTicker> tickers = complementOf(EnumSet.of(mainTicker));
tickersWithOutOneAnalysed = new ArrayList<GpwStockTicker>(tickers);
Thread threadOne = new Thread(new Runnable() {
public void run() {
firstPartTickers();
}
});
Thread threadTwo = new Thread(new Runnable() {
public void run() {
secondPartTickers();
}
});
threadOne.start();
threadTwo.start();
try {
threadOne.join();
threadTwo.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("Time of method (s): "+ (end-start) / 1000.0);
return correlationTreeSet;
}
private void firstPartTickers() {
for(int i = 0; i< tickersWithOutOneAnalysed.size()/2; i++) {
calculateCorrelation(i);
};
}
private void secondPartTickers() {
for(int i = tickersWithOutOneAnalysed.size()/2; i< tickersWithOutOneAnalysed.size(); i++) {
calculateCorrelation(i);
};
}
private void calculateCorrelation(int indexOfTicker) {
GpwStockTicker ticker = GpwStockTicker.valueOf(tickersWithOutOneAnalysed.get(indexOfTicker).name());
double [] closePricesToCompare = getClosePrices(getContent(ticker, size));
Double correlation = pearsonsCorrelation.correlation(closePricesAnalysed, closePricesToCompare);
StockStatistic stockCorrelation = new StockStatistic(correlation, ticker);
correlationTreeSet.add(stockCorrelation);
}
private List<StockDetails> getContent(GpwStockTicker ticker, int size) {
return stockDetailsRepository.findByStockTickerOrderByDateDesc(ticker, new PageRequest(1, size)).getContent();
}
private double[] getClosePrices(List<StockDetails> stockDetails) {
double[] closePrices = new double[stockDetails.size()];
int idx = 0;
for(StockDetails stds: stockDetails){
closePrices[idx++] = stds.getClosePrice().doubleValue();
}
return closePrices;
}
}实现了主要目标:多线程之前的时间是77.277秒,之后是43.534秒。但我想知道我的思维方式是否好。
发布于 2015-06-16 22:55:58
private void firstPartTickers() { for(int i = 0; i< tickersWithOutOneAnalysed.size()/2; i++) { calculateCorrelation(i); }; } private void secondPartTickers() { for(int i = tickersWithOutOneAnalysed.size()/2; i< tickersWithOutOneAnalysed.size(); i++) { calculateCorrelation(i); }; }
你有两种几乎相同的方法。这真的有必要吗?考虑以下方法:
private void calculateTickers(int start, int increment) {
for (int i = start; i < tickersWithOutOneAnalysed.size(); i += increment) {
calculateCorrelation(i);
}
}注意,我还在;循环之后删除了不必要的for。
现在你可以打电话了
calculateTickers(0, 2);
calculateTickers(1, 2);而不是
firstPartTickers(); secondPartTickers();
如果你以后想做第三条线,你可以说
calculateTickers(0, 3);
calculateTickers(1, 3);
calculateTickers(2, 3);发布于 2015-06-17 08:15:52
EnumSet<GpwStockTicker> tickers = complementOf(EnumSet.of(mainTicker));
tickersWithOutOneAnalysed = new ArrayList<GpwStockTicker>(tickers);我不知道为什么您选择将您的完美的EnumSet封装到一个ArrayList中。我的意思是,我知道您只是稍后使用List来检索索引,但我认为这是一个不必要的复杂,因为实现的限制……正如在mdfst13 13‘S答案中提到的,您将如何与更多的线程进行扩展?
答案是:ExecutorService。不久前,对于另一个类似的问题,我也有同样的答案,这里。如果有一个合适的ExecutorService实现,那么您的代码就可以简单地:
// ExecutorService executorService = Executors.<...>;
List<Future<StockStatistic>> results = new ArrayList<>();
for (GpwStockTicker ticker : complementOf(EnumSet.of(mainTicker))) {
results.add(executorService.submit(new Callable<StockStatistic>() {
@Override
public StockStatistic call() {
return new StockStatistic(
pearsonsCorrelation.correlation(closePricesAnalysed,
getClosePrices(getContent(ticker, size))), ticker);
}
});
}
for (Future<StockStatistic> future : results) {
correlationTreeSet.add(future.get());
}
// remember to shutdown() executorService too上面的例子是在Java 7中,如果您想探索的话,Java 8中也有一种更多的Stream-like方法。
https://codereview.stackexchange.com/questions/93767
复制相似问题