Skip to content

Instantly share code, notes, and snippets.

@wareya
Created January 27, 2025 02:34
Show Gist options
  • Select an option

  • Save wareya/52ac59709af286b9a5d55f8d76ebdb20 to your computer and use it in GitHub Desktop.

Select an option

Save wareya/52ac59709af286b9a5d55f8d76ebdb20 to your computer and use it in GitHub Desktop.

Revisions

  1. wareya created this gist Jan 27, 2025.
    124 changes: 124 additions & 0 deletions benchie.cpp
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,124 @@
    #include <stdio.h>
    #include <stdlib.h>
    #include <vector>
    #include <string>
    #include <chrono>
    using namespace std;

    #ifndef _WIN32
    #define redir_str " >/dev/null 2>/dev/null"
    #include <sys/times.h>
    #include <unistd.h>
    double get_cpu_time()
    {
    struct tms my_time;
    clock_t my_clock = times(&my_time);
    (void)my_clock;
    double utime = (double)my_time.tms_cutime / sysconf(_SC_CLK_TCK);
    double stime = (double)my_time.tms_cstime / sysconf(_SC_CLK_TCK);
    auto ret = utime;
    ret += stime;
    return ret;
    }
    void system_prepare();
    #else
    #define redir_str ""
    #define WIN32_LEAN_AND_MEAN
    #define VC_EXTRALEAN
    #include <windows.h>
    double _time = 0.0;
    double get_cpu_time() { return _time; }
    HANDLE subproc_id = 0;
    int system(char * cmd)
    {
    STARTUPINFO sinfo = {};
    sinfo.cb = sizeof(STARTUPINFO);
    sinfo.dwFlags = STARTF_USESTDHANDLES;

    HANDLE hNul = CreateFile("NUL", GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    sinfo.hStdOutput = hNul;
    sinfo.hStdError = hNul;

    PROCESS_INFORMATION pinfo = {};
    if (!CreateProcess(0, cmd, 0, 0, 0, 0, 0, 0, &sinfo, &pinfo))
    return -1;
    WaitForSingleObject(pinfo.hProcess, INFINITE);

    FILETIME ctime, xtime, stime, utime;
    GetProcessTimes(pinfo.hProcess, &ctime, &xtime, &stime, &utime);

    ULARGE_INTEGER stime_u, utime_u;
    stime_u.LowPart = stime.dwLowDateTime;
    stime_u.HighPart = stime.dwHighDateTime;
    utime_u.LowPart = utime.dwLowDateTime;
    utime_u.HighPart = utime.dwHighDateTime;

    // Convert to milliseconds
    double stime_s = stime_u.QuadPart / 10000000.0;
    double utime_s = utime_u.QuadPart / 10000000.0;
    _time += utime_s;
    _time += stime_s;

    DWORD ret;
    GetExitCodeProcess(pinfo.hProcess, &ret);

    CloseHandle(pinfo.hProcess);
    CloseHandle(pinfo.hThread);
    return ret;
    }
    #endif

    static inline double get_time()
    {
    auto now = std::chrono::steady_clock::now();
    auto duration = now.time_since_epoch();
    double ret = std::chrono::duration<double>(duration).count();
    return ret;
    }

    int main(int argc, char ** argv)
    {
    if (argc == 1)
    return puts("usage: benchify \"cmd1\" \"cmd2\" ...");
    vector<string> cmds;
    vector<vector<double>> times;
    vector<vector<double>> times2;
    for (size_t i = 1; i < (unsigned)argc; i++)
    {
    cmds.push_back(argv[i]);
    times.push_back({});
    }

    for (size_t i = 0; i < cmds.size(); i++)
    {
    printf("command %zd/%zd: %s...\n", i+1, cmds.size(), cmds[i].data());
    double t = 0.0;
    double t2 = 0.0;
    for (size_t j = 0; j < 10; j++)
    {
    double start = get_time();
    double ustart = get_cpu_time();

    auto ret = system((cmds[i] + redir_str).data());

    double uend = get_cpu_time();
    double end = get_time();
    if (ret)
    {
    printf("subcommand failed: %s\n", cmds[i].data());
    exit(ret);
    }
    times[i].push_back(end - start);
    t += times[i].back();
    t2 += uend-ustart;
    //printf("\r...%f ", times[i].back());
    printf("\r...%9.4f (cpu: %9.4f) (%zd/%d)", t/(j+1), uend-ustart, j+1, 10);
    fflush(stdout);
    }
    t /= 10.0;
    t2 /= 10.0;
    printf("\r %9.4f (cpu: %9.4f) (%d/%d)\n", t, t2, 10, 10);
    }

    return 0;
    }