如何使用自定义字符串快速填充缓冲区?

时间:2013-10-02 12:46:32

标签: c algorithm

我的要求是编写一个具有某种给定模式的文件(3个字节的char)。该文件可以是任何大小,例如如果文件大小为10个字节,则如果给定的模式为"abcabcabca",则内容将为"abc"

现在,memset不适用于多个字符。我的问题是:

  

使用这样的字符串填充缓冲区然后将其提供给写入系统调用的最快方法是什么?

我可以想到以下步骤

  1. 打开文件。
  2. 使用for循环和写入模式填充缓冲区(如果未指定,则最少1024个字符)。
  3. 循环直到文件大小。
  4. 我不确定如何快速使用给定模式填充缓冲区。

1 个答案:

答案 0 :(得分:3)

OP的算法很合理,只需要实现它。

使用循环memcpy()等编写缓冲区所花费的任何时间都会被文件I / O时间所淹没。因此,只需要适度优化缓冲区的形成。

真正是什么,是配置文件您的代码的好机会。尝试使用下面2中的时间2实现,看看时间差的结果。

int Fill_Basic(FILE *outf, size_t Length, char a, char b char c) {
  while (Length > 0) {
    if (Length > 0) {
      Length--;
      fputc(outf, a);
      }
    if (Length > 0) {
      Length--;
      fputc(outf, b);
      }
    if (Length > 0) {
      Length--;
      fputc(outf, c);
      }
    }
  return ferror(outf);
  }

int Fill_Faster(FILE *outf, size_t Length, char a, char b char c) {
  // A trick is to provide fwrite() with a "nice" buffer size.
  // This is often a power of 2 and is highly platform dependent, but a reasonable assertion.
  // Profiling would help access this.
  // Let's assume 1024
  size_t bsize = min(Length, 1024);
  char buf[bsize + 2];  // Allocate (3-1) extra.
  for (char *p = buf; p < &buf[bsize]; ) {
    *p++ = a;
    *p++ = b;
    *p++ = c;
    }
  // Optimization: each time through the loop, provide the buffer shifted as needed
  //  1st time "abcabc..."
  //  2nd time "bcabca..."
  //  3rd time "cabcab..."
  //  4th time "abcabc..."
  size_t Offset = 0;
  while (Length > 0) {
    for (size_t i=0; i<3; i++) {
      size_t t = min(Length, bsize);
      if (t != fwrite(&buffer[Offset], 1, t, outf)) handle_error();
      Length -= t;
      Offset += t;
      Offset %= 3;
      }
    }
  return ferror(outf);
  }