/* Step 2: the whole compiler inside a C binary, and what it costs to start. * * The startup number is measured around caml_startup itself, not with time(1) * on the process -- what a merged dev build would pay is the runtime coming up * and every module initialiser running, not exec and dynamic linking, which it * pays today anyway. */ #include #include #include #include #include #ifndef FLANSRC #define FLANSRC "test/programs/edn.flan" #endif static double ms_since(struct timespec a) { struct timespec b; clock_gettime(CLOCK_MONOTONIC, &b); return (b.tv_sec - a.tv_sec) * 1e3 + (b.tv_nsec - a.tv_nsec) / 1e6; } static const value *need(const char *n) { const value *f = caml_named_value(n); if (!f) fprintf(stderr, "spike: %s not registered\n", n); return f; } int main(int argc, char **argv) { struct timespec t0; const char *src = argc > 1 ? argv[1] : FLANSRC; const value *f; clock_gettime(CLOCK_MONOTONIC, &t0); caml_startup(argv); printf("caml_startup (runtime + every module initialiser): %.3f ms\n", ms_since(t0)); f = need("spike_footprint"); if (f) printf("linked-module footprint: %s\n", String_val(caml_callback(*f, Val_unit))); f = need("spike_compile"); if (f) { clock_gettime(CLOCK_MONOTONIC, &t0); printf("%s\n", String_val(caml_callback(*f, caml_copy_string(src)))); printf("first in-process compile (read+parse+check+emit): %.3f ms\n", ms_since(t0)); clock_gettime(CLOCK_MONOTONIC, &t0); caml_callback(*f, caml_copy_string(src)); printf("second, warm: %.3f ms\n", ms_since(t0)); } printf("spike: C main() still owns the process\n"); return 0; }