Python 实现速度比 C 更快



如果比较不应该以这种方式工作,我深表歉意。我是编程新手,只是好奇为什么会这样。

我有一个包含单词嵌入(4.5gb(的大型二进制文件。每行都有一个单词,后跟其嵌入,该嵌入由 300 个浮点值组成。我只是找到行总数。

对于C,我使用mmap:

int fd; 
struct stat sb; 
off_t offset = 0, pa_offset;
size_t length, i;
char *addr;
int count = 0;
fd = open("processed_data/crawl-300d-2M.vec", O_RDONLY);
if(fd == -1){
    handle_error("open");
    exit(1);
}
if(fstat(fd, &sb) < 0){
    handle_error("fstat");
    close(fd);
    exit(1);
}
pa_offset = offset & ~(sysconf(_SC_PAGE_SIZE) - 1);
if(offset >= sb.st_size){
    fprintf(stderr, "offset is past end of filen");
    exit(EXIT_FAILURE);
}
length = sb.st_size - offset;
addr = mmap(0, (length + offset - pa_offset), PROT_READ, MAP_SHARED, fd, pa_offset);
if (addr == MAP_FAILED) handle_error("mmap");
//Timing only this loop
clock_t begin = clock();
for(i=0;i<length;i++){
    if(*(addr+i) == 'n') count++;
}
printf("%dn", count);
clock_t end = clock();  
double time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
printf("%fn", time_spent);

这需要 11.283060 秒。

蟒:

file = open('processed_data/crawl-300d-2M.vec', 'r')
count = 0
start_time = timeit.default_timer()
for line in file:
    count += 1
print(count)
elapsed = timeit.default_timer() - start_time
print(elapsed)

这需要 3.0633065439997154 秒。

Python 代码不是读取每个字符来查找新行吗?如果是这样,为什么我的 C 代码效率如此低下?

很难说,因为我认为它将严重依赖于实现。但乍一看,你的 Python 和 C 程序之间的主要区别在于 C 程序使用 mmap .这是一个非常强大的工具(你在这里并不真正需要......(,因此可能会带来一些开销。由于参考 Python 实现是用 C 语言编写的,因此循环很可能

for line in file:
    count += 1

将以调用fgets的微小函数的循环结束。我敢打赌,使用fgets的朴素C程序会比Python等效程序略快,因为它可以节省所有的Python开销。但恕我直言,在 C 中使用 mmap 的效率低于在 Python 中使用 fgets 的效率也就不足为奇了

最新更新