2009-05-31 301 views
6

從一個插槽讀取1個字節與讀取大塊之間的性能差異有什麼區別?從一個插槽讀取1個字節與讀取大塊

我有一個C++應用程序,需要從Web服務器中拉出頁面,並逐行解析接收到的頁面。目前,我一次讀取1個字節,直到遇到CRLF或達到1024個字節的最大值。

如果以大塊(例如,每次1024字節)讀取更好的性能方面,關於如何實現我目前具有的相同行爲的任何想法(即能夠存儲和處理1個html行時間 - 直到CRLF沒有消耗後續字節呢)?

編輯:

我不能承受太大的緩衝區。由於應用程序在嵌入式設備中使用,因此代碼預算非常緊張。我更喜歡只保留一個固定大小的緩衝區,最好一次保存一個html行。這使得我的解析和其他處理變得簡單,因爲在任何時候我嘗試訪問解析緩衝區時,我都可以假設我正在處理一個完整的html行。

謝謝。

+0

你可以提供關於嵌入式設備的更多細節嗎?它甚至有一個操作系統嗎? – 2009-05-31 15:53:03

回答

4

如果直接從插座,而不是從可緩衝的中間較高級別的表示讀出,那麼毫無疑問,完全讀取1024字節,將它們放入RAM中,然後解析RAM中的數據會更好。

爲什麼?在套接字上讀取是一個系統調用,並且每次讀取都會導致上下文切換,這很昂貴。閱讀更多關於它的信息:IBM Tech Lib: Boost socket performances

+0

+1 - 我喜歡你的觀點,爲什麼閱讀大塊更好的性能。我想我可以解決尼爾巴特沃斯解決我第二個問題的答案。 =) – 2009-05-31 10:30:18

1

首先,最簡單的:

cin.getline(buffer,1024); 

其次,通常都是IO緩衝,所以你不必太擔心

三,CGI進程啓動成本通常更然後輸入處理(除它是巨大的 文件)...所以你可能不會去想它。

1

天兒真好,

一個大的性能命中通過一次做一個字節是你的上下文是從用戶的時間一遍遍進入系統時間。結束了。根本沒有效率。

抓取一個大塊,通常達到MTU大小,顯然更有效。

爲什麼不把內容掃描到一個向量中,然後遍歷它,尋找\ n's來將輸入分隔成多行輸入?

HTH

歡呼聲,

+0

是的,根據調用次數的不同,函數調用引起的相對開銷實際上可能在某個時刻變得很重要。 – none 2009-05-31 11:40:26

5

我無法對C++的評論,但是從其他平臺 - 是的,這可以使一個差異;特別是在代碼需要做的開關數量以及需要考慮流的異步性質的次數等方面。

但是真正的測試當然是對它進行配置。爲什麼不寫一個基本應用程序,通過這兩種方法通過任意文件攪動,併爲一些典型文件測試它......效果通常很驚人,如果的代碼是IO綁定。如果文件很小,並且您的應用程序運行時的大部分時間都花費在處理數據一旦在內存中,您不可能注意到任何差異。

1

你不是從一個套接字一次讀取一個字節,而是從C/C++ I/O系統一次讀取一個字節,如果你使用的是CGI,將會有一個字節緩衝所有的輸入插座。緩衝I/O的要點是讓程序員以便於他們處理的方式提供數據,所以如果您想一次處理一個字節,請繼續。

編輯:經過反思,從您的問題中不清楚您是在實施CGI還是僅僅使用它。您可以通過發佈代碼片段來說明這一點,該片段指示您當前如何閱讀該單字節。

如果您直接讀取套接字,那麼您應該簡單地將GET的整個響應讀入緩衝區,然後對其進行處理。這具有許多優點,包括性能和易於編碼。

如果正在linitted到一個小緩衝器,然後使用經典緩衝算法,如:

getbyte: 
    if buffer is empty 
     fill buffer 
     set buffer pointer to start of buffer 
    end 
    get byte at buffer pointer 
    increment pointer 
+0

不是。我正在讀取套接字。我正在向Web服務器發送HTTP GET請求,並從套接字讀取響應。我這樣做是因爲我需要完全呈現和解析的動態內容。 – 2009-05-31 09:40:36

+0

認爲我可以用這個算法稍作修改。我可以有兩個固定大小的緩衝區。一個讀取整個數據(比如512字節),掃描它並在另一個緩衝區中存儲一條完整的html行,我可以使用其他解析方法輕鬆訪問該行。我可以有一個更高效的套接字閱讀例程,並且可以保持我現在正在處理的易用性(即我的其他方法假設一個完整的html行)。謝謝。 =) – 2009-05-31 10:22:03

0

在操作系統層面上沒有任何區別,無論如何都會緩衝數據。但是,您的應用程序必須執行更多的代碼才能逐個「讀取」一個字節。

1

您可以使用fdopen()函數打開套接字文件descritpor。然後你已經緩衝IO,所以你可以調用fgets()或類似的描述符。