У меня есть файл данных почти 9 миллионов строк (скоро будет более 500 миллионов строк), и я ищу самый быстрый способ его чтения. Пять выровненных столбцов дополняются пробелами, поэтому я знаю, где в каждой строке искать два поля, которые я хочу.
Моя процедура Python занимает 45 секунд:
import sys,time
start = time.time()
filename = 'test.txt' # space-delimited, aligned columns
trans=[]
numax=0
for line in open(linefile,'r'):
nu=float(line[-23:-11]); S=float(line[-10:-1])
if nu>numax: numax=nu
trans.append((nu,S))
end=time.time()
print len(trans),'transitions read in %.1f secs' % (end-start)
print 'numax =',numax
тогда как подпрограмма, которую я придумал в C , более приятна на 4 секунды:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define BPL 47
#define FILENAME "test.txt"
#define NTRANS 8858226
int main(void) {
size_t num;
unsigned long i;
char buf[BPL];
char* sp;
double *nu, *S;
double numax;
FILE *fp;
time_t start,end;
nu = (double *)malloc(NTRANS * sizeof(double));
S = (double *)malloc(NTRANS * sizeof(double));
start = time(NULL);
if ((fp=fopen(FILENAME,"rb"))!=NULL) {
i=0;
numax=0.;
do {
if (i==NTRANS) {break;}
num = fread(buf, 1, BPL, fp);
buf[BPL-1]='\0';
sp = &buf[BPL-10]; S[i] = atof(sp);
buf[BPL-11]='\0';
sp = &buf[BPL-23]; nu[i] = atof(sp);
if (nu[i]>numax) {numax=nu[i];}
++i;
} while (num == BPL);
fclose(fp);
end = time(NULL);
fprintf(stdout, "%d lines read; numax = %12.6f\n", (int)i, numax);
fprintf(stdout, "that took %.1f secs\n", difftime(end,start));
} else {
fprintf(stderr, "Error opening file %s\n", FILENAME);
free(nu); free(S);
return EXIT_FAILURE;
}
free(nu); free(S);
return EXIT_SUCCESS;
}
Решения в Fortran, C ++ и Java занимают промежуточное время (27 секунд, 20 секунд, 8 секунд).
Мой вопрос таков: совершил ли я какие-либо грубые ошибки в вышеперечисленном (особенно код C )? И есть ли способ ускорить рутину Python? Я быстро понял, что хранение моих данных в массиве кортежей лучше, чем создание экземпляра класса для каждой записи.