#[cfg(not(unix))]
fn main() {
eprintln!("`flamegraph_consumer` example needs pprof's signal-driven sampler; supported on Unix only.");
}
#[cfg(unix)]
fn main() {
imp::run();
}
#[cfg(unix)]
mod imp {
use dmc_codegen::{HtmlEmitter, MdxBodyEmitter, NodeSink, Walker};
use dmc_diagnostic::Code;
use dmc_diagnostic::metadata::{Origin, SourceMeta};
use dmc_lexer::Lexer;
use dmc_parser::Parser;
use dmc_transform::{Pipeline, PipelineConfig};
use duck_diagnostic::DiagnosticEngine;
use pprof::ProfilerGuardBuilder;
use std::fs;
use std::path::PathBuf;
use std::sync::Arc;
use std::time::Instant;
fn load_corpus() -> (Vec<(String, String)>, &'static str) {
let candidates = [
(
"/run/media/wildduck/duck1/wildduck/@duck/@duck-ui/apps/duck/content/.dmc-cache/preprocessed",
"preprocessed mirror",
),
("../@duck-ui/apps/duck/content/.dmc-cache/preprocessed", "preprocessed mirror"),
("../../@duck-ui/apps/duck/content/.dmc-cache/preprocessed", "preprocessed mirror"),
("/run/media/wildduck/duck1/wildduck/@duck/@duck-ui/apps/duck/content", "raw content tree (no preMdx pass)"),
("../@duck-ui/apps/duck/content", "raw content tree (no preMdx pass)"),
("../../@duck-ui/apps/duck/content", "raw content tree (no preMdx pass)"),
];
let (root, kind) = candidates
.iter()
.map(|(p, k)| (PathBuf::from(p), *k))
.find(|(p, _)| p.exists())
.expect("apps/duck corpus not found - checkout @duck-ui beside this repo, or run `bun run build:docs` once");
let mut out = Vec::new();
let mut stack = vec![root.clone()];
while let Some(d) = stack.pop() {
for ent in fs::read_dir(&d).unwrap_or_else(|e| panic!("read_dir {}: {e}", d.display())) {
let Ok(ent) = ent else { continue };
let p = ent.path();
if p.is_dir() {
stack.push(p);
continue;
}
let Some(ext) = p.extension().and_then(|s| s.to_str()) else { continue };
if ext != "mdx" && ext != "md" {
continue;
}
let rel = p.strip_prefix(&root).unwrap().to_string_lossy().into_owned();
let src = fs::read_to_string(&p).unwrap_or_default();
if !src.is_empty() {
out.push((rel, src));
}
}
}
(out, kind)
}
fn compile_one(rel: &str, source: &str, pipeline: &Pipeline) {
let meta = Arc::new(SourceMeta { path: Arc::from(rel), origin: Origin::Inline(rel.to_string().leak()) });
let mut diag = DiagnosticEngine::<Code>::new();
let mut lex = Lexer::new(source, meta.clone(), &mut diag);
let _ = lex.scan_tokens();
let mut doc = {
let mut parser = Parser::new(lex.tokens, meta.clone(), &mut diag);
parser.parse()
};
pipeline.run(&mut doc, &meta, &mut diag);
let mut html = HtmlEmitter::new();
let mut body = MdxBodyEmitter::new();
let mut sinks: Vec<&mut dyn NodeSink> = vec![&mut html, &mut body];
Walker::new(&doc).walk(sinks.as_mut_slice());
let _ = html.into_parts();
let _ = body.into_parts();
}
pub fn run() {
let out_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.parent()
.unwrap()
.join("duck-benchmarks/phase-7-g-hardening/flamegraph");
fs::create_dir_all(&out_dir).unwrap();
let svg_path = out_dir.join("duck-ui.svg");
let txt_path = out_dir.join("duck-ui.txt");
let (corpus, corpus_kind) = load_corpus();
eprintln!("loaded {} mdx files from apps/duck {corpus_kind}", corpus.len());
let pipeline_cfg = PipelineConfig::default();
let pipeline = Pipeline::with_defaults_for(&pipeline_cfg);
let guard = ProfilerGuardBuilder::default()
.frequency(997)
.blocklist(&["libc", "libgcc", "pthread", "vdso"])
.build()
.expect("pprof guard");
let started = Instant::now();
let mut full_passes = 0u64;
let mut files_compiled = 0u64;
while started.elapsed().as_secs_f32() < 5.0 {
for (rel, src) in &corpus {
compile_one(rel, src, &pipeline);
files_compiled += 1;
}
full_passes += 1;
}
let elapsed = started.elapsed();
let report = guard.report().build().expect("build report");
let summary = format!(
"duck-ui flamegraph fixture\n\
-------------------------\n\
corpus : {} mdx files (apps/duck {})\n\
full passes : {}\n\
compiles : {}\n\
wall-clock : {:.2}s ({:.1} ms/file avg over all compiles)\n\
sampling : pprof @ 997 Hz, signal-driven (no perf, no sudo)\n\
\n\
Open `duck-ui.svg` in a browser. Click frames to zoom; click the\n\
title bar to reset. Search bar in the top-right.\n",
corpus.len(),
corpus_kind,
full_passes,
files_compiled,
elapsed.as_secs_f32(),
elapsed.as_secs_f64() * 1000.0 / files_compiled.max(1) as f64,
);
fs::write(&txt_path, summary).expect("write txt");
let f = fs::File::create(&svg_path).expect("open svg");
report.flamegraph(f).expect("write svg");
eprintln!("compiled {files_compiled} files across {full_passes} full passes in {:.2}s", elapsed.as_secs_f32());
eprintln!("wrote {}", svg_path.display());
eprintln!("wrote {}", txt_path.display());
}
}