JAVA,10萬(wàn)個(gè)Int值相加,怎么實(shí)現(xiàn)更有效率
問(wèn)題描述
10萬(wàn)個(gè)int值相加,怎么實(shí)現(xiàn)更有效率。今天收拾面試題,看到以前被人問(wèn)的這個(gè)題目。思索無(wú)果歡迎大家來(lái)討論討論!
昨天根據(jù)fonxian的回答試試了一下,發(fā)現(xiàn)并沒(méi)有什么區(qū)別!我的實(shí)現(xiàn)有問(wèn)題?使用線程的算法,可能是因?yàn)榫€程需要額外的開(kāi)銷(xiāo)所以會(huì)慢一點(diǎn)。使用map的就忽略了吧,map版本改了好多次都打不到想要的效果,看來(lái)map的開(kāi)銷(xiāo)好大。分開(kāi)計(jì)算和合并計(jì)算并沒(méi)有什么區(qū)別,分開(kāi)計(jì)算的好處根本看不出來(lái)~~~~
2017-5-10感謝thomastao 的提醒,我重新整理了下方法,可以看出來(lái)點(diǎn)門(mén)道了。我水平有限就不總結(jié)了。各位看看就好!
public static void main(String[] args) {IntSumTest t = new IntSumTest(10000000);Long startDate1 = new Date().getTime();//方法注釋后的數(shù)值為執(zhí)行時(shí)間(毫秒)//先用map去重,然后相乘。最后將結(jié)果相加t.mapCount(); //7255 8251 8002 7355//開(kāi)啟多個(gè)線程相加,結(jié)果記錄到sum數(shù)組中。最后將sum數(shù)組相加。//t.threadCount(); //5 5 4 4 5 4 5 4 4 4//一個(gè)線程相加分10次相加,結(jié)果記錄到sum數(shù)組中。最后將sum數(shù)組相加。//t.reduceCount(); //4 2 3 3 3 3 4 3 2 3//直接相加//t.count();//11 10 10 10 10 10 12 13 11 11//使用計(jì)數(shù)方法//t.countSum(); //14 15 14 16 12 13 11 12 12 13Long endDate1 = new Date().getTime();System.out.println(endDate1- startDate1 ); }
public class IntSumTest { int[] valueNum = new int[10000000];//1000w個(gè)數(shù) public IntSumTest(int maxNum){Random r = new Random();for(int i=0;i<valueNum.length;i++){ valueNum[i] = r.nextInt(maxNum);} } /** * 直接計(jì)算 * @return */ public long count(){long sum = 0;for(int i=0;i<valueNum.length;i++){ sum+= valueNum[i];}return sum; } /** * 使用計(jì)數(shù)方法計(jì)算 * 理論上的好處在于java棧內(nèi)的管理方式是所有成員變量都會(huì)記錄 * @return */ public long countSum(){long sum = 0;for(int i=0;i<valueNum.length;i++){ sum = sum( sum,valueNum[i]);}return sum; } public long sum(long sum ,int num){return sum+num; } /** * 使用數(shù)組計(jì)數(shù),然后在各個(gè)數(shù)字相乘,得到結(jié)果 * 該方法的好處在于可以釋放大量對(duì)象 * 缺點(diǎn)在于,如果數(shù)字的分布范圍太大,效果就不明顯 */ public long mapCount(){long sum = 0;Map<Integer,Integer> map = new HashMap<Integer,Integer>();for(int i=0;i<valueNum.length;i++){ map.put(valueNum[i],map.get(valueNum[i])==null?0:map.get(valueNum[i])+1);}for (Map.Entry<Integer, Integer> entry : map.entrySet()) { sum+= entry.getKey()*entry.getValue();}return sum; } /** * 多線程計(jì)算,分10組計(jì)算,分別匯總結(jié)果 */ public long threadCount(){long sum = 0;long[] sumNum = new long[10];for (int i = 0; i < 10; i++) { MyThread my = new MyThread(sumNum,valueNum,i); my.run();}for (int i = 0; i < 10; i++) { sum += sumNum[i];}return sum; } /** * 分10組計(jì)算,分別匯總結(jié)果 */ public long reduceCount(){long sum = 0;long[] sumNum = new long[10];for (int i = 0; i < 10; i++) { int temp = i*10000; long max = temp+10000; for (int j = temp; j < max; j++) {sumNum[i]+= valueNum[j]; }}for (int i = 0; i < 10; i++) { sum += sumNum[i];}return sum; }}
問(wèn)題解答
回答1:用MapReduce的思想或者多線程解決。10w個(gè)整數(shù)map成n組(例如10組),每組只需要計(jì)算1w的數(shù)的sum,然后reduce歸約,10個(gè)sum相加。
回答2:一般來(lái)說(shuō)先肉眼看有沒(méi)有規(guī)律,有規(guī)律了用公式算,沒(méi)規(guī)律了就老老實(shí)實(shí)的一個(gè)一個(gè)加吧。。。
相關(guān)文章:
1. javascript - 我是做web前端的,公司最近有一個(gè)項(xiàng)目關(guān)于數(shù)據(jù)統(tǒng)計(jì)的!2. javascript - 只是想用node建立一個(gè)簡(jiǎn)單的服務(wù)器3. javascript - 在ie下為什么會(huì)出現(xiàn)這種情況呢 《 無(wú)法獲取未定義或 null 引用的屬性“l(fā)ength”》 ?請(qǐng)大神指教。4. javascript - 如何使用loadash對(duì)[object,object,object]形式的數(shù)組進(jìn)行比較5. javascript - vue過(guò)渡效果 css過(guò)渡 類(lèi)名的先后順序6. android - 有數(shù)據(jù)要處理的時(shí)候如何使用rxJava進(jìn)行異步處理數(shù)據(jù)7. javascript - vuejs+elementui 購(gòu)物車(chē)價(jià)格計(jì)算,點(diǎn)擊加減號(hào)修改數(shù)量總價(jià)都不會(huì)改變,但是計(jì)算執(zhí)行了8. android - 哪位大神知道java后臺(tái)的api接口的對(duì)象傳到前端后輸入日期報(bào)錯(cuò),是什么情況?求大神指點(diǎn)9. javascript - url參數(shù)值有特殊符號(hào)“+”,該怎么進(jìn)行轉(zhuǎn)義?10. javascript - 微信支付:H5調(diào)起支付API,直接說(shuō)支付失敗
