有效的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
?
一些忠告:
- 删除
malloc
和realloc
上的所有强制转换; 它们不是必需的,并且使代码混乱; - 而不是重复调用
getchar
,使用fread
或fgets
(取决于你是在读二进制文本还是文本); - 请记住,
realloc
可能会返回NULL,因此您希望将结果分配给临时值,否则您将失去对原始指针的跟踪并最终导致泄漏内存; - 为每个输入块使用静态分配的缓冲区;
- 在对象上使用
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 */