2009-05-31 88 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()或类似的描述符。