[問題] 請問list的效率以及讀檔問題

看板C_and_CPP作者 (15357)時間10年前發表 (2014/12/19 11:01), 10年前編輯推噓6(6025)
留言31則, 9人參與, 最新討論串1/1
各位高手好, 小弟目前有一隻非常要求執行效率的程式 本來是用JAVA在寫,且也已經盡量的去改善效能 但始終突破不了紀錄保持人的速度, 最近想說改用C++來寫寫看 可是光是第一步讀檔步驟,速度馬上就輸了java的bufferedReader 我想說把C++的讀檔也改成可以像JAVA那樣有緩衝區,減少從硬碟讀取檔案的次數 但每次檔案讀到尾端時,就會出現亂碼,我緩衝區的大小設1024 我在猜是不是因為最後檔案接近尾端時,檔案內容根本不足1024,所以才會出現亂碼? 想請各位高手指點我一下 ifstream fileInput; fileInput.open ("1.txt", ios::binary ); char buff[1024]; string str; while(fileInput){ fileInput.read(buff,1024); str = buff; cout<<str<<endl; } 這是我用小檔案測試讀檔的內容:http://ppt.cc/EnhB 如果真得是因為檔案最後的內容不足1024。因此出現亂碼 那想請問該如何才能知道最後還剩多少內容還沒讀取? 以便讓我修改緩衝區的大小 或者說我這實做方法根本就是錯誤的,謝謝。 另外就是雖然C++的list跟JAVA的linkedList內部實作上也許不太一樣 但原理應該是大同小異(我猜的) 不曉得為什麼同樣都是push_back相同的數量 但c++的list卻比java慢很多@@ 例如說我塞一千個string進去,C++要0.6秒,JAVA卻只要0.009秒 整個速度有著很大的差距@@ 想請問說是有什麼關鍵的東西是我沒注意到的嗎? 感謝各位 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 1.174.86.224 ※ 文章網址: http://www.ptt.cc/bbs/C_and_CPP/M.1418986898.A.68B.html

12/19 19:12, , 1F
用C的Standard library
12/19 19:12, 1F

12/19 20:13, , 2F
每一個iter都把buff清空成/0看看
12/19 20:13, 2F

12/19 20:13, , 3F
\0
12/19 20:13, 3F

12/19 20:13, , 4F
檔尾的處理請直接參照此網頁範例 http://goo.gl/LW3GP0
12/19 20:13, 4F

12/19 20:14, , 5F
\0
12/19 20:14, 5F

12/19 20:14, , 6F
該範例中的 is.gcount() 就會是最後一次成功讀取的數量
12/19 20:14, 6F

12/19 20:15, , 7F
塞進去 std::list 會比較慢,可能是有多餘的字串拷貝
12/19 20:15, 7F

12/19 20:16, , 8F
可考慮搭配 std::shared_ptr<std::string> 來嘗試改善
12/19 20:16, 8F

12/19 20:23, , 9F
另外,講求性能的檔案讀取請愛用 memory-mapped file
12/19 20:23, 9F

12/19 20:27, , 10F
可直接將檔案映射為一個記憶體位址,實在是快速又方便
12/19 20:27, 10F

12/19 20:32, , 11F
你的list是arraylist還是LinkedList?? c++是要用vector吧
12/19 20:32, 11F

12/19 20:32, , 12F
你沒丟程式碼感覺不出你的問題在哪 請樓下隔空抓藥
12/19 20:32, 12F

12/19 20:33, , 13F
你編譯的是 release mode 還是 debug mode也有差
12/19 20:33, 13F

12/19 20:34, , 14F
是linklist沒錯 你的list改存string*會快很多
12/19 20:34, 14F

12/19 21:53, , 15F
請問為什麼用ios::binary啊?C++字串的結尾都是用'\0'來標記
12/19 21:53, 15F

12/19 21:54, , 16F
但是binary沒有
12/19 21:54, 16F

12/19 21:58, , 17F
用 getline 直接存到 string,c++比 java慢,實在不服氣
12/19 21:58, 17F

12/19 22:19, , 18F
先把完整程式貼上來再說吧 不是每個人都有買水晶球好嗎= =
12/19 22:19, 18F

12/19 22:30, , 19F
>iwami 如果是用 std::string (像原 PO) 那就不需要 \0
12/19 22:30, 19F

12/20 02:34, , 20F
抱歉,我指的是char[]char*這類東西
12/20 02:34, 20F
感謝各位前輩的幫助以及建議 不過d大提到的用release執行的話會有差,我改過去後確實速度有提升 再額外選擇『啟動但不偵錯』的話, 不管是讀檔還是push_back速度真的有快超多 原來是我自己搞烏龍了...抱歉抱歉 可是想請問一下為什麼list改存string*會快很多? 感覺上不是一樣的意思嗎@@ 另外我用ios::binary是因為查教學時大家都用這種才跟著用的@@ 不然我原本是用ios::in,不過也許是我的寫法拙劣的關係,速度上感覺不出差異 而讀取檔案的部分我原本也是用getLine,想說這樣很方便, 不過不曉得為什麼我用ifstream::getLine讀取一行後在轉string的速度 會比直接用string::getLine的速度快很多orz... 再次感謝各位前輩的幫助,謝謝~ ※ 編輯: googled (1.174.86.224), 12/20/2014 02:55:33

12/20 02:59, , 21F
String是一個object,你push進去的時候會把內容全部複製
12/20 02:59, 21F

12/20 02:59, , 22F
一遍 (整個字串);
12/20 02:59, 22F

12/20 03:01, , 23F
String *只是指標(ie. 記憶體位置),只有64 bits
12/20 03:01, 23F

12/20 03:01, , 24F
(假設是64位元OS)
12/20 03:01, 24F

12/20 03:06, , 25F
但是如果用指標要小心scope,小心dangling pointer
12/20 03:06, 25F

12/20 03:07, , 26F
然後用char string + fgets 會快更多
12/20 03:07, 26F

12/20 03:17, , 27F
linked list 自己寫也會快一些
12/20 03:17, 27F

12/20 03:19, , 28F
或是換GCC,下O3(優化),應該又會更快;反正方法很多
12/20 03:19, 28F

12/20 10:11, , 29F
若是 VS2013 可直接用 std::shared_ptr<std::string>
12/20 10:11, 29F

12/20 10:12, , 30F
raw pointer 也沒什麼不好,要小心 memory leak 就是
12/20 10:12, 30F

12/22 18:19, , 31F
我明白了,非常謝謝各位前輩的建議跟教學,感謝
12/22 18:19, 31F
文章代碼(AID): #1Kb0MIQB (C_and_CPP)