利用DeepSeek将Rust程序的缓冲输出改写为C语言实现提高输出效率

前面多语言测试中,遇到一个难以置信的问题,rust的输出到文件比c语言还快,这是不合情理的,通过对两者输出语句的比较,发现了不同。
rust程序在输出到stdout前有这么一句

let mut writer = BufWriter::with_capacity(64 * 1024, stdout.lock());

而c语言是直接输出。
将上述语句发给DeepSeek,它给出了等价的C语言实现。

#define BUFFER_SIZE (64 * 1024)  // 64KB 缓冲区

    // 设置 stdout 缓冲
    char buffer[BUFFER_SIZE];
    if (setvbuf(stdout, buffer, _IOFBF, sizeof(buffer)) != 0) {
        perror("setvbuf failed");
        return EXIT_FAILURE;
    }
    // 原输出语句
    // 刷新缓冲区
    if (fflush(stdout) != 0) {
        perror("fflush failed");
        return EXIT_FAILURE;
    }

加入上述语句的c代码编译运行情况如下:

gcc sort_lines_buf.c -o csortbuf -O3
time ./csortbuf varchar.txt >vvc.txt

real    0m1.367s
user    0m0.431s
sys     0m0.086s
time ./csortbuf varchar.txt >/dev/null

real    0m0.792s
user    0m0.406s
sys     0m0.063s

而加入缓冲前

time ./c_sort varchar.txt >vvc.txt

real    0m3.568s
user    0m0.439s
sys     0m0.226s
time ./c_sort varchar.txt >/dev/null

real    0m0.758s
user    0m0.335s
sys     0m0.080s

可见,缓冲后输出到文件的时间缩短到原来的1/3,而不输出文件的保持不变。
需要指出,这个缓冲区并非越大越好,它受限于栈容量,如果改成从堆分配和文件大小一样的内存做缓冲区,反而比不缓冲更慢。
完整带缓冲输出c代码摘录如下。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#define MAX_LINES 1000000  // 最多100万行
#define BUFFER_SIZE (64 * 1024) // 64KB 缓冲区
int compare_offsets(const void *a, const void *b) {
    return strcmp(*(const char **)a, *(const char **)b);
}

int main(int argc, char *argv[]) {
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <filename>\n", argv[0]);
        return 1;
    }

    // 打开文件并获取大小
    int fd = open(argv[1], O_RDONLY);
    if (fd == -1) {
        perror("open");
        return 1;
    }

    struct stat st;
    if (fstat(fd, &st) == -1) {
        perror("fstat");
        close(fd);
        return 1;
    }

    size_t file_size = st.st_size;

    // 分配缓冲区并读取文件
    char *buf = malloc(file_size + 1);
    if (!buf) {
        perror("malloc");
        close(fd);
        return 1;
    }

    if (read(fd, buf, file_size) != file_size) {
        perror("read");
        free(buf);
        close(fd);
        return 1;
    }
    close(fd);
    buf[file_size] = '\0';  // 确保以null结尾

    // 记录每行起始地址
    char *lines[MAX_LINES];
    size_t line_count = 0;

    lines[line_count++] = buf;  // 第一行开始

    // 遍历缓冲区,记录每行起始地址并将\n替换为\0
    for (char *p = buf; *p && line_count < MAX_LINES; p++) {
        if (*p == '\n') {
            *p = '\0';
            if (*(p + 1)) {  // 如果不是文件末尾
                lines[line_count++] = p + 1;
            }
        }
    }

    // 对行指针数组进行排序
    qsort(lines, line_count, sizeof(char *), compare_offsets);
 
    // 设置 stdout 缓冲
        
    char buffer[BUFFER_SIZE];
    if (setvbuf(stdout, buffer, _IOFBF, sizeof(buffer)) != 0) {
        perror("setvbuf failed");
        return EXIT_FAILURE;
    }
    
    // 写入数据
    for (int i = 0; i < line_count; i++) {
        if (printf("%s\n", lines[i]) < 0) {
            perror("printf failed");
            return EXIT_FAILURE;
        }
    }
    
    // 刷新缓冲区
    if (fflush(stdout) != 0) {
        perror("fflush failed");
        return EXIT_FAILURE;
    }
    free(buf);
    
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值