Repository: valkey-io/valkey
File: src/valkey-benchmark.c (C)

Code before:
                printf("%3.3f%% <= %.3f milliseconds (cumulative count %lld)\n", percentile, value, cumulative_count);
            }
            /* After the 2 milliseconds latency to have percentages split
             * by decimals will just add a lot of noise to the output. */
            if (iter.highest_equivalent_value > 2000) {
                hdr_iter_linear_set_value_units_per_bucket(&iter, 1000);
            }
            previous_cumulative_count = cumulative_count;
        }
        printf("\n");
        printf("Summary:\n");
        printf("  throughput summary: %.2f requests per second\n", reqpersec);
        printf("  latency summary (msec):\n");
        printf("    %9s %9s %9s %9s %9s %9s\n", "avg", "min", "p50", "p95", "p99", "max");
        printf("    %9.3f %9.3f %9.3f %9.3f %9.3f %9.3f\n", avg, p0, p50, p95, p99, p100);

        /* RPS analysis - always show when --rps is used */
        if (config.rps > 0) {
            float target_rps = (float)config.rps;
            float achievement_pct = (reqpersec / target_rps) * 100.0f;

            printf("\n  RPS Analysis:\n");
            printf("    Target RPS: %.0f\n", target_rps);
            printf("    Actual RPS: %.2f (%.1f%% of target)\n", reqpersec, achievement_pct);

            // ADD RPS PERCENTILE ANALYSIS
            if (config.rps_histogram && config.rps_histogram->total_count > 0) {
                const float rps_p1 = hdr_value_at_percentile(config.rps_histogram, 1.0);
                const float rps_p10 = hdr_value_at_percentile(config.rps_histogram, 10.0);
                const float rps_p50 = hdr_value_at_percentile(config.rps_histogram, 50.0);
                // const float rps_p90 = hdr_value_at_percentile(config.rps_histogram, 90.0);
                // const float rps_p99 = hdr_value_at_percentile(config.rps_histogram, 99.0);

                printf("    RPS Performance Guarantees:\n");
                printf("      99%% of time: RPS ≥ %.0f (%.1f%% of target)\n",
                       rps_p1, (rps_p1 / target_rps) * 100);
                printf("      90%% of time: RPS ≥ %.0f (%.1f%% of target)\n",
                       rps_p10, (rps_p10 / target_rps) * 100);
                printf("      50%% of time: RPS ≥ %.0f (%.1f%% of target)\n",
                       rps_p50, (rps_p50 / target_rps) * 100);

                // Bottleneck analysis using P1 (99% of time achieved this or better)
                if (rps_p1 >= 0.99 * target_rps) {
                    printf("    Status: GOOD PERFORMANCE\n");
                    printf("    99%% of time achieved 99%% of target RPS.\n");
                } else if (rps_p1 >= 0.90 * target_rps) {
                    printf("    Status: BOTTLENECK DETECTED\n");
                    printf("    99%% of time achieved 90%% of target RPS.\n");
                } else {
                    printf("    Status: SEVERE BOTTLENECK DETECTED\n");
                    printf("    Performance significantly below target.\n");

Review comment (suggestion):
```suggestion
            /* ADD RPS PERCENTILE ANALYSIS */
```

Code after:
        struct hdr_iter_percentiles *percentiles = &iter.specifics.percentiles;
        while (hdr_iter_next(&iter)) {
            const double value = iter.highest_equivalent_value / 1000.0f;
            const double percentile = percentiles->percentile;
            const long long cumulative_count = iter.cumulative_count;
            if (previous_cumulative_count != cumulative_count || cumulative_count == total_count) {
                printf("%3.3f%% <= %.3f milliseconds (cumulative count %lld)\n", percentile, value, cumulative_count);
            }
            previous_cumulative_count = cumulative_count;
        }
        printf("\n");
        printf("Cumulative distribution of latencies:\n");
        previous_cumulative_count = -1;
        hdr_iter_linear_init(&iter, config.latency_histogram, 100);
        while (hdr_iter_next(&iter)) {
            const double value = iter.highest_equivalent_value / 1000.0f;
            const long long cumulative_count = iter.cumulative_count;
            const double percentile = ((double)cumulative_count / (double)total_count) * 100.0;
            if (previous_cumulative_count != cumulative_count || cumulative_count == total_count) {
                printf("%3.3f%% <= %.3f milliseconds (cumulative count %lld)\n", percentile, value, cumulative_count);
            }
            /* After the 2 milliseconds latency to have percentages split
             * by decimals will just add a lot of noise to the output. */
            if (iter.highest_equivalent_value > 2000) {
                hdr_iter_linear_set_value_units_per_bucket(&iter, 1000);
            }
            previous_cumulative_count = cumulative_count;
        }
        printf("\n");
        printf("Summary:\n");
        printf("  throughput summary: %.2f requests per second\n", reqpersec);
        printf("  latency summary (msec):\n");
        printf("    %9s %9s %9s %9s %9s %9s\n", "avg", "min", "p50", "p95", "p99", "max");
        printf("    %9.3f %9.3f %9.3f %9.3f %9.3f %9.3f\n", avg, p0, p50, p95, p99, p100);
    } else if (config.csv) {
        printf("\"%s\",\"%.2f\",\"%.3f\",\"%.3f\",\"%.3f\",\"%.3f\",\"%.3f\",\"%.3f\"\n", config.title, reqpersec, avg,
               p0, p50, p95, p99, p100);
    } else {
        printf("%*s\r", config.last_printed_bytes, " "); // ensure there is a clean line
        printf("%s: %.2f requests per second, p50=%.3f msec\n", config.title, reqpersec, p50);
    }
}

static void initBenchmarkThreads(void) {
    int i;
    if (config.threads) freeBenchmarkThreads();
    config.threads = zmalloc(config.num_threads * sizeof(benchmarkThread *));
    for (i = 0; i < config.num_threads; i++) {
        benchmarkThread *thread = createBenchmarkThread(i);
        config.threads[i] = thread;
    }