You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编写C语言测试程序:无需重启被测程序测试多语言数独求解器性能

这是个很棒的需求——确实,像Java这类启动开销大的语言,反复重启会严重影响性能测试的公平性。我来分享一个用C实现的持久化被测程序的测试框架思路和代码示例,完美适配你的数独求解器测试场景:

核心设计思路

我们的目标是只启动一次被测程序,通过双向管道和它建立持续通信:测试程序批量发送数独谜题,被测程序依次返回求解结果,全程保持被测进程运行,彻底规避启动开销。同时要精准统计每个谜题的求解耗时,并验证结果的正确性。

具体实现步骤与代码示例

1. 建立双向进程通信通道

用C的pipe()创建两个管道:一个负责向被测程序发送输入(数独谜题),另一个负责接收被测程序的输出(求解结果)。通过fork()+exec()启动被测程序,并将它的标准输入/输出重定向到管道。

2. 批量测试流程

  • 预加载所有数独谜题到内存(比如从文件读取,确保测试过程无IO干扰)
  • 启动被测程序并建立通信
  • 遍历每个谜题:
    • 记录求解开始时间
    • 发送谜题到被测程序
    • 等待并接收求解结果
    • 记录结束时间,计算耗时
    • 验证解的合法性
  • 测试完成后,终止被测程序并回收进程

3. 核心代码片段

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <string.h>
#include <signal.h>

#define BUFFER_SIZE 1024

// 数独验证函数:检查解是否符合原始谜题规则
int sudoku_validate(const char *puzzle, const char *solution) {
    // 基础长度检查(标准数独是81字符)
    if (strlen(puzzle) != 81 || strlen(solution) != 81) return 0;
    
    // 验证原始已知数是否匹配
    for (int i = 0; i < 81; i++) {
        if (puzzle[i] != '.' && puzzle[i] != solution[i]) {
            return 0;
        }
    }

    // 这里可以补充完整的数独合法性检查(每行/列/3x3宫无重复)
    // 省略具体实现,你可以根据数独规则自行编写
    return 1;
}

int main(int argc, char *argv[]) {
    if (argc < 2) {
        fprintf(stderr, "Usage: %s <被测程序命令>\n", argv[0]);
        exit(EXIT_FAILURE);
    }

    int to_child[2], from_child[2];
    pid_t pid;
    char buffer[BUFFER_SIZE];
    struct timeval start, end;
    double elapsed;

    // 创建双向管道
    if (pipe(to_child) == -1 || pipe(from_child) == -1) {
        perror("Failed to create pipes");
        exit(EXIT_FAILURE);
    }

    // 分叉进程启动被测程序
    pid = fork();
    if (pid == -1) {
        perror("Failed to fork process");
        exit(EXIT_FAILURE);
    }

    if (pid == 0) {
        // 子进程:重定向标准IO到管道
        close(to_child[1]);  // 关闭不需要的写端
        close(from_child[0]); // 关闭不需要的读端

        dup2(to_child[0], STDIN_FILENO);  // 绑定stdin到输入管道
        dup2(from_child[1], STDOUT_FILENO); // 绑定stdout到输出管道

        // 启动被测程序(支持任意可执行程序,比如java SudokuSolver)
        execvp(argv[1], &argv[1]);
        perror("Failed to execute target program");
        exit(EXIT_FAILURE);
    }

    // 父进程(测试程序)
    close(to_child[0]);  // 关闭不需要的读端
    close(from_child[1]); // 关闭不需要的写端

    // 示例测试用例(实际可以从文件读取)
    char *puzzles[] = {
        "53..7....6..195....98....6.8...6...34..8.3..17...2...6.6....28....419..5....8..79",
        "....9..5.1.....3.5.8....7.9...4..8.6.3..2...1.7....6.3.....1.2..8....4..6......."
    };
    int num_puzzles = sizeof(puzzles)/sizeof(puzzles[0]);

    for (int i = 0; i < num_puzzles; i++) {
        // 记录求解开始时间
        gettimeofday(&start, NULL);

        // 发送谜题(末尾加换行符作为被测程序的输入结束标记)
        write(to_child[1], puzzles[i], strlen(puzzles[i]));
        write(to_child[1], "\n", 1);

        // 读取求解结果
        ssize_t bytes_read = read(from_child[0], buffer, BUFFER_SIZE-1);
        if (bytes_read <= 0) {
            fprintf(stderr, "Puzzle %d: Failed to receive solution\n", i+1);
            break;
        }
        buffer[bytes_read] = '\0';

        // 记录结束时间并计算耗时
        gettimeofday(&end, NULL);
        elapsed = (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec)/1e6;

        // 验证结果并输出统计
        if (sudoku_validate(puzzles[i], buffer)) {
            printf("Puzzle %d: Solved in %.4f seconds\n", i+1, elapsed);
        } else {
            printf("Puzzle %d: Invalid solution\n", i+1);
        }
    }

    // 终止被测程序并回收进程
    kill(pid, SIGTERM);
    waitpid(pid, NULL, 0);

    // 清理资源
    close(to_child[1]);
    close(from_child[0]);
    return EXIT_SUCCESS;
}
关键注意事项
  • 输出缓冲问题:很多语言的标准输出默认是行缓冲或全缓冲,被测程序必须在输出结果后立即刷新输出(比如Java用System.out.flush(),Python用print(..., flush=True)),否则测试程序会一直阻塞等待输入。如果无法修改被测程序,可以考虑在测试程序中设置管道为非阻塞模式(用fcntl()),但处理逻辑会更复杂。
  • 超时机制:如果某个谜题求解时间过长,建议用select()监听管道读端并设置超时时间,避免测试程序卡住。
  • 时间统计精度:如果需要更精准的计时,推荐使用clock_gettime(CLOCK_MONOTONIC, &ts),它不受系统时间调整的影响,比gettimeofday更适合测量程序运行时间。
  • 跨语言兼容性:只要被测程序支持从标准输入读取谜题、向标准输出输出结果,不管是Java、Python、C++还是其他语言实现的求解器,都能完美适配这个测试框架。

内容的提问来源于stack exchange,提问作者EmptyArsenal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:21:43