亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

java 多線程訪問mongodb速度和單線程差不多

java 多線程訪問mongodb速度和單線程差不多

胡子哥哥 2019-04-07 09:38:24
我現在基于probalisticlatentsemanticindexing(plsa)做圖像檢索,我的方法和這篇論文很像,需要計算一個條件概率p(z|w,v,d),我直接定義成了“doublepzdwtwv[][][][];”簡單地說,z是主題,w是英文單詞,v是視覺單詞,d是文檔,大小分別為12100500*7000,就是12個主題,100個英文單詞,500個視覺單詞,7000個文檔,double型的話算下來大概32G,其中z和d的數目是確定的,每個d的w和v的數目是不確定的。因為數組不能全部放進內存,所以把它放進數據庫中,我的數據庫是這樣設計的,把四維數組拆成二維數組,每次讀或寫一個二維數組。我使用了40個線程跑算法,數據庫中在collection中每個鍵對應的值是一個二維數組,每次計算完這個二維數組后就寫入數據庫,我的方法是這樣的:publicsynchronizedvoidupdate(intd,intt,double[][][]topic_pro){if(ifTrainset)mongo.update(true,(d+1)*100+t,topic_pro[t]);elsemongo.update(false,(d+1)*100+t,topic_pro[t]);}pzdwtwv和pzdwtwv_test是不同的collection。mongo.update方法是這樣的:publicvoidupdate(booleanifTrainset,intkey,double[][]new_value){BasicDBObjectquery=newBasicDBObject().append("key",key);BasicDBObjectupdated_element=newBasicDBObject();updated_element.append("$set",newBasicDBObject().append("value",new_value));if(ifTrainset){p_z_d_wt_wv.update(query,updated_element,true,false);}else{p_z_d_wt_wv_test.update(query,updated_element,true,false);}}另外,運行程序的時候,cpu利用率很低,大概7%~8%左右,但是內存幾乎達到100%。請問這個怎么解決
查看完整描述

2 回答

?
藍山帝景

TA貢獻1843條經驗 獲得超7個贊

對于題主的問題,簡單分析一下:
synchronized是不必要的,mongodb本身是線程安全的,而你的update方法只是一個簡單的切換;
從你的問題描述上看,應該是計算密集型的任務,對與計算密集型的任務,一般ThreadNums=CpuNums+1,過多的線程數導致上下文頻繁的切換,反而會影響效率;
沒有給出mongodb的版本信息,在2.2版本之前,mongodb的lock粒度是server級別,在2.2級別之后,lock粒度是db級別,對于粗粒度的鎖,除非你的數據庫進行了sharing,否則盡管兩個collection是不同的,單次每次寫(更新)操作時,仍然會等待鎖,這也是與單線程性能差不多的主要原因;
benchmark測試,盡量需要減少硬件、軟件等外部因素的影響。對于你的問題描述,無法看出這些,只有一個簡單的多線程與單線程的區別,這在JVM層面的影響因素就有很多了,所以無法簡單的給出性能的優劣評價。
                            
查看完整回答
反對 回復 2019-04-07
?
慕斯709654

TA貢獻1840條經驗 獲得超5個贊

本來就應該差不多。
首先要搞明白的一點是,你的瓶頸在哪里?
其次,CPU密集型任務跑那么多線程竟然沒有慢很多?你有多少個CPU核?這種事情一般是一個核一個線程,多了反而因為上下文切換浪費CPU時間。
另外,你確定你需要synchronized?
                            
查看完整回答
反對 回復 2019-04-07
  • 2 回答
  • 0 關注
  • 338 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號