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

标签 c algorithm

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

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

What is the quickest way to fill a buffer with such a string and then provide it to the write system call?

我可以想到以下步骤

  1. 打开文件。
  2. 使用 for 循环和写入模式填充缓冲区(如果未指定,则最少 1024 个字符)。
  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);
  } 

关于c - 如何用自定义字符串快速填充缓冲区?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19137244/

相关文章:

c++ - 为什么 C/C++ 字符串文字声明必须是单行的?

C Do 循环错误解释条件

c++ - Sieve of Sundaram 和 Sieve of Atkin 生成素数列表的比较

algorithm - 为什么插入一个排序数组 O(n)?

c - 如何在c中的2个进程之间传递整数值

c - atomic_dec_if_positive 是如何原子化的?

c - Arduino uno无法上传

algorithm - 为什么补体的公式不起作用?

java - 使用比较器对列表列表进行排序

algorithm - 为什么单链表有多个头是一件好事?