从套接字读取1个字节一次与读取大块

时间:2009-05-31 09:16:24

标签: c++ c sockets cgi

有什么区别 - 性能方面 - 从套接字读取1个字节一次到读取大块?

我有一个C ++应用程序需要从Web服务器提取页面并逐行解析收到的页面。目前,我一次读取1个字节,直到遇到CRLF或达到1024字节的最大值。

如果读取大块(例如一次1024个字节)在性能方面要好得多,那么关于如何实现我目前所拥有的相同行为的任何想法(即能够一次存储和处理1个html行) - 直到CRLF还没有消耗后续字节?)

编辑:

我买不起太大的缓冲区。由于应用程序用于嵌入式设备,因此我的代码预算非常紧张。我更喜欢只保留一个固定大小的缓冲区,最好一次只保留一个html行。这使我的解析和其他处理变得容易,因为我随时尝试访问缓冲区进行解析,我可以假设我正在处理一个完整的html行。

感谢。

7 个答案:

答案 0 :(得分:5)

我不能评论C ++,但是来自其他平台 - 是的,这可能会产生的差异;特别是代码需要执行的交换机数量,以及需要担心流的异步性等的次数。

但真正的考验当然是剖析它。为什么不编写一个基本的应用程序,使用这两种方法搅拌任意文件,并测试一些典型的文件...效果通常是惊人的,如果代码是IO绑定。如果文件很小并且大部分应用运行时花费在处理数据一旦存储在内存中,您就不会注意到任何差异。

答案 1 :(得分:4)

如果您是直接从套接字读取,而不是从可以缓冲的中间高级表示中读取,那么毫无疑问,最好完全读取1024个字节,将它们放入缓冲区的RAM中,然后解析RAM中的数据。

为什么呢?读取套接字是系统调用,它会在每次读取时引起上下文切换,这很昂贵。阅读更多相关信息:IBM Tech Lib: Boost socket performances

答案 2 :(得分:1)

首先也是最简单的:

cin.getline(buffer,1024);

其次,通常所有IO都是缓冲的,所以你不必太担心

第三,CGI流程启动通常比输入处理花费更多(除非它是巨大的 文件)...所以你可能不会想到它。

答案 3 :(得分:1)

天儿真好,

通过一次一个字节执行一次大的性能命中是您的上下文从一次又一次从用户时间进入系统时间。结束了。根本没用。

抓住一个大块,通常达到MTU大小,效率明显提高。

为什么不将内容扫描到一个矢量中并迭代查找\ n来将输入分成Web输入行?

HTH

欢呼声,

答案 4 :(得分:1)

您不是一次从套接字读取一个字节,而是从C / C ++ I / O系统一次读取一个字节,如果您使用CGI,则可以使用CGI的所有输入来缓冲所有输入。插座。缓冲I / O的重点是使程序员可以方便地处理数据,因此如果要一次处理一个字节,请继续。

编辑:经过反思,您的问题不清楚您是在实施CGI还是仅仅使用它。您可以通过发布一个代码片段来阐明这一点,该代码片段指示您当前读取该字节的读取方式。

如果您正在直接读取套接字,那么您应该只是将对GET的整个响应读入缓冲区然后进行处理。这具有许多优点,包括性能和编码的简易性。

如果你是一个小缓冲区,那么使用经典的缓冲算法,如:

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

答案 5 :(得分:1)

您可以使用fdopen()函数打开套接字文件descritpor。然后你有缓冲IO,所以你可以在该描述符上调用fgets()或类似的东西。

答案 6 :(得分:0)

操作系统级别没有区别,无论如何都要缓冲数据。但是,您的应用程序必须执行更多代码才能一次“读取”一个字节。

相关问题