zoukankan      html  css  js  c++  java
  • C程序优化 I/O篇(转)

    C程序优化 - I/O篇

    liyuming1978(原作)

      如果有文件读写的话,那么对文件的访问将是影响程序运行速度的一大因素。提高文件访问速度的主要办法有两个:一是采用内存映射文件,二是使用内存缓冲。下面是一组测试数据(见《UNIX环境高级编程》3.9节),显示了用18种不同的缓存长度,读1,468 ,802字节文件所得到的结果。

    缓冲大小
    用户CPU(秒)
    系统CPU(秒)
    时钟时间(秒)
    循环次数(秒)
    1
    23.8
    397.9
    423.4
    1 468 802
    2
    12.3
    202.0
    215.2
    734 401
    4
    6.1
    100.6
    107.2
    367 201
    8
    3.0
    50.7
    54.0
    183 601
    16
    1.5
    25.3
    27.0
    91 801
    32
    0.7
    12.8
    13.7
    45 901
    64
    0.3
    6.6
    7.0
    22 951
    128
    0.2
    3.3
    3.6
    11 476
    256
    0.1
    1.8
    1.9
    5 738
    512
    0.0
    1.0
    1.1
    2 869
    1 024
    0.0
    0.6
    0.6
    1 435
    2 048
    0.0
    0.4
    0.4
    718
    4 096
    0.0
    0.4
    0.4
    359
    8 192
    0.0
    0.3
    0.3
    180
    16 384
    0.0
    0.3
    0.3
    90
    32 768
    0.0
    0.3
    0.3
    45
    65 536
    0.0
    0.3
    0.3
    23
    131 072
    0.0
    0.3
    0.3
    12

      可见,一般的当内存缓冲区大小为8192的时候,性能就已经是最佳的了,这也就是为什么在H.263等图像编码程序中,缓冲区大小为8192的原因(有的时候也取2048大小)。使用内存缓冲区方法的好处主要是便于移植,占用内存少,便于硬件实现等。下面是读取文件的C伪码:

    int Len ;
    BYTE buffer[8192] ;
    ASSERT(buffer==NULL) ;
    If buffer is empty
    {
      Len=read(File,buffer,8192) ;
      If(len==0) No data and exit ;
    }

      但是如果内存比较大的时候,采用内存映射文件可以达到更佳性能,并且编程实现简单。内存映射的具体使用说明见msdn October 2001中的Platform SDK:Documentation—Base Services—File Storage—File Mapping。

    下面是一点建议:
    ① 内存映射文件不能超过虚拟内存的大小,最好也不要太大,如果内存映射文件接近虚拟内存大小的时候,反而会大大降低程序的速度(其实是因为虚拟内存不足导致系统运行效率降低),这个时候,可以考虑分块映射,但是我觉得如果这样,还不如直接使用内存缓冲来得直接一些。

    ② 可以将两种方法统一使用,如我在编大图像文件数据处理的时候(因为是Unix工作站,内存很大GB单位)使用了内存映射文件,但是为了最佳性能,也使用了一行图像缓存,这样在读取文件中数据的时候,就保证了仅仅是顺序读写(内存映射文件中,对顺序读写有专门的优化)。

    ③ 在写文件的时候使用内存映射文件要有一点小技巧:应该先创建足够大的文件,然后将这个文件映射,在处理完这个文件的时候,用函数SetFilePointer和SetEndOfFile来对文件进行截尾。

    ④ 对内存映射文件进行操作与对内存进行操作类似(使用起来就象数组一样),那么如果有大块数据读写的时候,切记使用memcpy()函数(或者CopyMemory()函数)

      总之,如果要使用内存映射文件,必须:1.处理的文件比较的小,2.处理的文件很大,但是运行环境内存也很大,并且一般在运行该程序的时候不运行其他消耗内存大的程序,同时用户对速度有特别的要求,而且对内存占用没有什么要求。如果以上两个条件不满足的时候,建议使用内存缓冲区的办法。

     转自(C程序优化 - I/O篇

    liyuming1978(原作)

      如果有文件读写的话,那么对文件的访问将是影响程序运行速度的一大因素。提高文件访问速度的主要办法有两个:一是采用内存映射文件,二是使用内存缓冲。下面是一组测试数据(见《UNIX环境高级编程》3.9节),显示了用18种不同的缓存长度,读1,468 ,802字节文件所得到的结果。

    缓冲大小
    用户CPU(秒)
    系统CPU(秒)
    时钟时间(秒)
    循环次数(秒)
    1
    23.8
    397.9
    423.4
    1 468 802
    2
    12.3
    202.0
    215.2
    734 401
    4
    6.1
    100.6
    107.2
    367 201
    8
    3.0
    50.7
    54.0
    183 601
    16
    1.5
    25.3
    27.0
    91 801
    32
    0.7
    12.8
    13.7
    45 901
    64
    0.3
    6.6
    7.0
    22 951
    128
    0.2
    3.3
    3.6
    11 476
    256
    0.1
    1.8
    1.9
    5 738
    512
    0.0
    1.0
    1.1
    2 869
    1 024
    0.0
    0.6
    0.6
    1 435
    2 048
    0.0
    0.4
    0.4
    718
    4 096
    0.0
    0.4
    0.4
    359
    8 192
    0.0
    0.3
    0.3
    180
    16 384
    0.0
    0.3
    0.3
    90
    32 768
    0.0
    0.3
    0.3
    45
    65 536
    0.0
    0.3
    0.3
    23
    131 072
    0.0
    0.3
    0.3
    12

      可见,一般的当内存缓冲区大小为8192的时候,性能就已经是最佳的了,这也就是为什么在H.263等图像编码程序中,缓冲区大小为8192的原因(有的时候也取2048大小)。使用内存缓冲区方法的好处主要是便于移植,占用内存少,便于硬件实现等。下面是读取文件的C伪码:

    int Len ;
    BYTE buffer[8192] ;
    ASSERT(buffer==NULL) ;
    If buffer is empty
    {
      Len=read(File,buffer,8192) ;
      If(len==0) No data and exit ;
    }

      但是如果内存比较大的时候,采用内存映射文件可以达到更佳性能,并且编程实现简单。内存映射的具体使用说明见msdn October 2001中的Platform SDK:Documentation—Base Services—File Storage—File Mapping。

    下面是一点建议:
    ① 内存映射文件不能超过虚拟内存的大小,最好也不要太大,如果内存映射文件接近虚拟内存大小的时候,反而会大大降低程序的速度(其实是因为虚拟内存不足导致系统运行效率降低),这个时候,可以考虑分块映射,但是我觉得如果这样,还不如直接使用内存缓冲来得直接一些。

    ② 可以将两种方法统一使用,如我在编大图像文件数据处理的时候(因为是Unix工作站,内存很大GB单位)使用了内存映射文件,但是为了最佳性能,也使用了一行图像缓存,这样在读取文件中数据的时候,就保证了仅仅是顺序读写(内存映射文件中,对顺序读写有专门的优化)。

    ③ 在写文件的时候使用内存映射文件要有一点小技巧:应该先创建足够大的文件,然后将这个文件映射,在处理完这个文件的时候,用函数SetFilePointer和SetEndOfFile来对文件进行截尾。

    ④ 对内存映射文件进行操作与对内存进行操作类似(使用起来就象数组一样),那么如果有大块数据读写的时候,切记使用memcpy()函数(或者CopyMemory()函数)

      总之,如果要使用内存映射文件,必须:1.处理的文件比较的小,2.处理的文件很大,但是运行环境内存也很大,并且一般在运行该程序的时候不运行其他消耗内存大的程序,同时用户对速度有特别的要求,而且对内存占用没有什么要求。如果以上两个条件不满足的时候,建议使用内存缓冲区的办法。

  • 相关阅读:
    销售类
    语法
    编辑技巧 word
    assert
    游戏摘录
    游戏类链接 财富导图
    读书笔记之C# delegate
    c# socket传输struct类型
    关于wcf中一些重要词语解释
    asp.net CROSS-PAGE POSTING
  • 原文地址:https://www.cnblogs.com/Fightingbirds/p/2862142.html
Copyright © 2011-2022 走看看