Progtwigción efectiva de lectura estándar

¿Alguien puede ayudarme a optimizar el código para leer la entrada estándar? Aquí está lo que tengo ahora:

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; } 

Pregunta: ¿estás leyendo datos binarios o de texto de stdin ? Si el texto, ¿por qué estás utilizando caracteres unsigned char ?

Algún consejo:

  1. realloc caer todos los moldes en malloc y realloc ; no son necesarios y abarrotan el código;
  2. En lugar de llamar repetidamente a getchar , usa fread o fgets (dependiendo de si estás leyendo binario o texto);
  3. Recuerde que realloc puede potencialmente devolver NULL, por lo que desea asignar el resultado a un valor temporal, de lo contrario perderá la pista del puntero original y terminará la memoria con pérdidas;
  4. Utilice un búfer asignado estáticamente para cada fragmento de entrada;
  5. Use sizeof en objetos, no en tipos; es un poco más limpio y lo protege en caso de que cambien los tipos (por ejemplo, T *p = malloc(sizeof *p * number_of_elements);

Versión limpia, asumiendo que tiene la intención de usar caracteres sin firmar:

 #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; } } 

Intente leer fragmentos fijos de al menos 8192 bytes. No utilice la entrada de un solo char ya que es bastante lento.

¿Por qué quieres “optimizar” el código?

¿Lo hiciste?
¿Encontraste que era demasiado lento?
¿Estás listo para cronometrar las nuevas versiones?
¿Se da cuenta de que el tiempo de ejecución del código depende de muchos factores (como la carga actual del procesador, la cantidad de usuarios activos, la actividad del disco, …, …)

La mejor optimización que puede hacer es comenzar con un valor muy grande para malloc (y posiblemente redistribuir después de que se hayan leído todos los datos).

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