高效的复制记忆

时间:2015-04-16 16:44:26

标签: c

我继承了以下代码:

void *buf1 = calloc(1,total_buf_size);
//build buf1 up with memcpy 
int index;
void *buf2 = buf1;

for (index = 0; index < log->numentries; index++)
{
  logentry_t *entry = (logentry_t*)&log->entries[index];

  memcpy(buf2,entry->entryname,sizeof(entry->entryname));
  buf2 = buf2 + (int)sizeof(entry->entryname);
  memcpy(buf2,&entry->entrysize,sizeof(entry->entrysize));
  buf2 = buf2 + (int)sizeof(entry->entrysize);
  memcpy(buf2,&entry->updatesize,sizeof(entry->updatesize));
  buf2 = buf2 + (int)sizeof(entry->updatesize);
  memcpy(buf2,&entry->numupdates,sizeof(entry->numupdates));
  buf2  = buf2 + (int)sizeof(entry->numupdates);

  int j;
  for (j = 0; j < entry->numupdates; j++)
  {   
    memcpy(buf2,&entry->offsets[j],sizeof(entry->offsets[j]));
    buf2 = buf2 + (int)sizeof(entry->offsets[j]);
  }

  int k;
  for (k = 0; k < entry->numupdates; k++)
  {
    memcpy(buf2,&entry->sizes[k],sizeof(entry->sizes[k]));
    buf2 = buf2 + (int)sizeof(entry->sizes[k]);      
  }


  memcpy(buf2,entry->data,entry->updatesize);
}

我有一个事务日志,我正在迭代并需要将每个日志条目的数据写入文件中的一行。目前,它使用memcpy构建所有条目的缓冲区,并将它们一次性写入文件。有没有更好的方法将内存复制和扩展到buf2?

2 个答案:

答案 0 :(得分:0)

我不确定您正在寻找什么样的效率,但这里是将每个日志条目记录写入文件然后为每次迭代重置缓冲区buf2的示例。因此,您可以将buf1大小(由total_buf_size定义)减少到只适合一个日志条目记录的内容:

void *buf1 = calloc(1,total_buf_size);
//With this method total_buf_size can be reduced to fit just one log entry record

//build buf1 up with memcpy 
int index;
void *buf2 = buf1;

FILE * pFile;
pFile = fopen ("myfile.txt","w");

for (index = 0; index < log->numentries; index++)
{
  logentry_t *entry = (logentry_t*)&log->entries[index];

  memcpy(buf2,entry->entryname,sizeof(entry->entryname));
  buf2 = buf2 + (int)sizeof(entry->entryname);
  memcpy(buf2,&entry->entrysize,sizeof(entry->entrysize));
  buf2 = buf2 + (int)sizeof(entry->entrysize);
  memcpy(buf2,&entry->updatesize,sizeof(entry->updatesize));
  buf2 = buf2 + (int)sizeof(entry->updatesize);
  memcpy(buf2,&entry->numupdates,sizeof(entry->numupdates));
  buf2  = buf2 + (int)sizeof(entry->numupdates);

  int j;
  for (j = 0; j < entry->numupdates; j++)
  {   
    memcpy(buf2,&entry->offsets[j],sizeof(entry->offsets[j]));
    buf2 = buf2 + (int)sizeof(entry->offsets[j]);
  }

  int k;
  for (k = 0; k < entry->numupdates; k++)
  {
    memcpy(buf2,&entry->sizes[k],sizeof(entry->sizes[k]));
    buf2 = buf2 + (int)sizeof(entry->sizes[k]);      
  }


  memcpy(buf2,entry->data,entry->updatesize);

  fwrite(buf2, sizeof(logentry_t), sizeof(buf2), pFile);

  memset(&buf2, 0, sizeof(buf2)); //clear it out
  buf2 = buf1; //reset the pointer
}

fclose(pFile);
free(buf2);

答案 1 :(得分:0)

在我的评论下面,我的意思是:

FILE *file = fopen("log.file", "a"); // assert(file != NULL);

for (int i = 0; i < log->numentries, i++) {
    logentry_t *e = (logentry_t*)&log->entries[i];

#define OUT(x) do { fwrite(x, sizeof(x), 1, file) } while (0)
    OUT(e->entryname);
    OUT(e->entrysize);
    OUT(e->updatesize);
    OUT(e->numupdates);

    for (int j = 0; j < e->numupdates; j++)
        OUT(&e->offsets[j]);

    for (int k = 0; k < e->numupdates; k++)
        OUT(&entry->sizes[k]);

    fwrite(e->data, e->updatesize, 1, file);
#undef OUT
}
fflush(file);

...

即。你根本不需要buf,因为fwrite已经在stdio.h层执行缓冲。此代码未经过测试,可能包含任何类型的错误。

另请注意,将原始数据写入日志文件可能会导致在不同平台甚至编译器上出现小/大端和整数大小问题(尽管后者的可能性较小,具体取决于logentry_t字段的实际类型)。您可以考虑将整数数据字段预格式化为可移植的固定大小表示形式,例如htons / htonl或甚至printf("%ld", (long)x)等文本。