tricu

A lazy functional language based on Tree Calculus
Log | Files | Refs | README | LICENSE

core_bench.c (2952B)


      1 #define _POSIX_C_SOURCE 200809L
      2 /* Same public C calls for both linkages. Fresh suspensions each round; timing
      3  * separates ABI/graph construction from demanding the completed reduction. */
      4 #include "tricu.h"
      5 #include <assert.h>
      6 #include <stdio.h>
      7 #include <stdlib.h>
      8 #include <string.h>
      9 #include <time.h>
     10 #include <sys/resource.h>
     11 
     12 static double now(void) {
     13     struct timespec ts;
     14     assert(clock_gettime(CLOCK_MONOTONIC, &ts) == 0);
     15     return (double)ts.tv_sec + (double)ts.tv_nsec / 1e9;
     16 }
     17 static tricu_handle node(tricu_context ctx, tricu_handle a, tricu_handle b) {
     18     tricu_handle out;
     19     assert(tricu_fork(ctx, a, b, &out) == TRICU_OK);
     20     return out;
     21 }
     22 static void drop(tricu_context ctx, tricu_handle h) {
     23     assert(tricu_release(ctx, h) == TRICU_OK);
     24 }
     25 int main(int argc, char **argv) {
     26     assert(argc == 3);
     27     const int distribution = strcmp(argv[1], "distribution") == 0;
     28     assert(distribution || strcmp(argv[1], "constant") == 0);
     29     const unsigned long n = strtoul(argv[2], NULL, 10);
     30     assert(n > 0 && n <= 1048576);
     31     tricu_init();
     32     /* Warm up once; all seven measured rounds create independent graphs. */
     33     for (int round = -1; round < 7; ++round) {
     34         tricu_context ctx;
     35         tricu_handle leaf, term;
     36         assert(tricu_context_new(&ctx) == TRICU_OK);
     37         assert(tricu_leaf(ctx, &leaf) == TRICU_OK);
     38         assert(tricu_retain(ctx, leaf, &term) == TRICU_OK);
     39         const double begin = now();
     40         for (unsigned long i = 0; i < n; ++i) {
     41             tricu_handle k = node(ctx, leaf, term), fn = k, next;
     42             if (distribution) {
     43                 /* S (K (K previous)) t t = previous. Exercises distribution
     44                  * while retaining a known complete result without a codec. */
     45                 tricu_handle kk = node(ctx, leaf, k), skk;
     46                 assert(tricu_stem(ctx, kk, &skk) == TRICU_OK);
     47                 fn = node(ctx, skk, leaf);
     48                 drop(ctx, kk);
     49                 drop(ctx, skk);
     50             }
     51             assert(tricu_apply(ctx, fn, leaf, &next) == TRICU_OK);
     52             if (distribution) drop(ctx, fn);
     53             drop(ctx, k);
     54             drop(ctx, term);
     55             term = next;
     56         }
     57         const double built = now();
     58         tricu_handle reduced;
     59         assert(tricu_reduce(ctx, term, &reduced) == TRICU_OK);
     60         const double demanded = now();
     61         uint32_t kind = 987;
     62         assert(tricu_kind(ctx, reduced, &kind) == TRICU_OK && kind == TRICU_LEAF);
     63         drop(ctx, reduced);
     64         drop(ctx, term);
     65         drop(ctx, leaf);
     66         assert(tricu_context_free(ctx) == TRICU_OK);
     67         struct rusage usage;
     68         assert(getrusage(RUSAGE_SELF, &usage) == 0);
     69         if (round >= 0) printf("{\"kind\":\"%s\",\"size\":%lu,\"round\":%d,"
     70             "\"build_seconds\":%.9f,\"reduce_seconds\":%.9f,\"peak_rss_kib\":%ld}\n",
     71             argv[1], n, round, built-begin, demanded-built, usage.ru_maxrss);
     72     }
     73     return 0;
     74 }