有效的stdin阅读c编程

任何人都可以帮助我优化代码来读取标准输入。 这就是我现在拥有的:

unsigned char *msg; size_t msgBytes = 0; size_t inputMsgBuffLen = 1024; if ( (msg = (unsigned char *) malloc(sizeof(unsigned char) * inputMsgBuffLen) ) == NULL ) { quitErr("Couldn't allocate memmory!", EXIT_FAILURE); } for (int c; (c = getchar()) != EOF; msgBytes++) { if (msgBytes >= (inputMsgBuffLen)) { inputMsgBuffLen <<= 1; if ( ( msg = (unsigned char *)realloc(msg, sizeof(unsigned char) * inputMsgBuffLen) ) == NULL) { free(msg); quitErr("Couldn't allocate more memmory!", EXIT_FAILURE); } } msg[msgBytes] = (unsigned char)c; } 

问题:您是从stdin读取二进制文本还是文本数据? 如果是文本,为什么使用unsigned char

一些忠告:

  1. 删除mallocrealloc上的所有强制转换; 它们不是必需的,并且使代码混乱;
  2. 而不是重复调用getchar ,使用freadfgets (取决于你是在读二进制文本还是文本);
  3. 请记住, realloc可能会返回NULL,因此您希望将结果分配给临时值,否则您将失去对原始指针的跟踪并最终导致泄漏内存;
  4. 为每个输入块使用静态分配的缓冲区;
  5. 在对象上使用sizeof ,而不是类型; 它有点干净,它可以在类型改变的情况下保护你(例如, T *p = malloc(sizeof *p * number_of_elements);

假设您打算使用无符号字符的清理版本:

 #define inputBufSize 1024 unsigned char *msg = NULL; size_t msgBytes = 0; size_t inputMsgBufSize = 0; unsigned char inputBuffer[inputBufSize]; size_t bytesRead = 0; while ((bytesRead = fread( inputBuffer, // target buffer sizeof inputBuffer, // number of bytes in buffer 1, // number of buffer-sized elements to read stdin)) > 0) { unsigned char *tmp = realloc(msg, inputMsgBufSize + bytesRead)); if (tmp) { msg = tmp; memmove(&msg[inputMsgBufSize], inputBuffer, bytesRead); inputMsgBufSize += bytesRead; } else { printf("Ran out of memory\n"); free(msg); break; } } 

尝试读取至少8192个字节的固定块。 不要使用单个字符输入,因为它很慢。

为什么要“优化”代码?

你有时间吗?
你觉得它太慢了吗?
你准备好为新版本计时吗?
您是否意识到代码的计时运行时间取决于许多因素(如当前处理器负载,活动用户数,磁盘活动,…,……)

您可以做的最佳优化是以malloc的非常大的值开始(并且可能在读取所有数据后重新分配)。

 size_t inputMsgBuffLen = 400000000; /* approx 400 mega */