首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >一种被分析股票报价器相关性的计算

一种被分析股票报价器相关性的计算
EN

Code Review用户
提问于 2015-06-16 16:56:03
回答 2查看 85关注 0票数 2

我有一个股票代码,然后从数据库我得到一个分析的股票(股票)的详细信息。在循环中,我将分析的滴答器的细节与其他代码的细节进行比较,计算相关性,然后将其添加到treeSet中。

这是我第一次使用多线程,我希望在更短的时间内执行该方法。我不确定这个解决方案。你能检查一下我的代码并判断一下吗?

这是我的服务:

代码语言:javascript
复制
@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秒。但我想知道我的思维方式是否好。

EN

回答 2

Code Review用户

发布于 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); }; }

你有两种几乎相同的方法。这真的有必要吗?考虑以下方法:

代码语言:javascript
复制
    private void calculateTickers(int start, int increment) {
        for (int i = start; i < tickersWithOutOneAnalysed.size(); i += increment) {
            calculateCorrelation(i);
        }
    }

注意,我还在;循环之后删除了不必要的for

现在你可以打电话了

代码语言:javascript
复制
                calculateTickers(0, 2);
                calculateTickers(1, 2);

而不是

firstPartTickers(); secondPartTickers();

如果你以后想做第三条线,你可以说

代码语言:javascript
复制
                calculateTickers(0, 3);
                calculateTickers(1, 3);
                calculateTickers(2, 3);
票数 2
EN

Code Review用户

发布于 2015-06-17 08:15:52

代码语言:javascript
复制
EnumSet<GpwStockTicker> tickers = complementOf(EnumSet.of(mainTicker));
tickersWithOutOneAnalysed = new ArrayList<GpwStockTicker>(tickers);

我不知道为什么您选择将您的完美的EnumSet封装到一个ArrayList中。我的意思是,我知道您只是稍后使用List来检索索引,但我认为这是一个不必要的复杂,因为实现的限制……正如在mdfst13 13‘S答案中提到的,您将如何与更多的线程进行扩展?

答案是:ExecutorService。不久前,对于另一个类似的问题,我也有同样的答案,这里。如果有一个合适的ExecutorService实现,那么您的代码就可以简单地:

代码语言:javascript
复制
// 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方法。

票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/93767

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档