Skip to content

Commit

Permalink
add criterion benches
Browse files Browse the repository at this point in the history
  • Loading branch information
arlyon committed Apr 16, 2024
1 parent dde1091 commit 7ef28f6
Show file tree
Hide file tree
Showing 2 changed files with 152 additions and 0 deletions.
4 changes: 4 additions & 0 deletions packages/next-swc/crates/next-build-test/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,7 @@ criterion = { version = "0.5", features = ["async_tokio"] }
gitoxide-core = "0.35.0"
gix = { version = "0.61.0", features = ["blocking-network-client", "blocking-http-transport-reqwest"] }
tempdir = "0.3.7"

[[bench]]
name = "bench"
harness = false
148 changes: 148 additions & 0 deletions packages/next-swc/crates/next-build-test/benches/bench.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
use std::time::Duration;

use anyhow::Context;
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use next_api::project::{ProjectContainer, ProjectOptions};
use turbo_tasks::TurboTasks;
use turbo_tasks_malloc::TurboMalloc;
use turbopack_binding::turbo::tasks_memory::MemoryBackend;

/// Clones a repo down into a tmp folder and produces a ProjectOptions that can
/// build it.
fn init_bench(
src: &str,
install_command: &str,
package_path: Option<&str>,
next_config: String,
js_config: String,
) -> (ProjectOptions, tempdir::TempDir) {
let tmp = tempdir::TempDir::new("turbo-bench").unwrap();

let clone = std::process::Command::new("git")
.arg("clone")
.arg("--depth")
.arg("1")
.arg(src)
.arg(tmp.path())
.status()
.unwrap();

std::process::Command::new("sh")
.arg("-c")
.current_dir(tmp.path())
.arg(install_command)
.status()
.unwrap();

let project_path = package_path
.map(|pp| tmp.path().join(pp))
.unwrap_or_else(|| tmp.path().to_owned());

(
ProjectOptions {
project_path: project_path.to_str().unwrap().to_owned(),
root_path: tmp.path().to_str().unwrap().to_owned(),
env: vec![],
define_env: next_api::project::DefineEnv {
client: vec![],
edge: vec![],
nodejs: vec![],
},
watch: false,
dev: false,
next_config,
js_config,
},
tmp,
)
}

#[global_allocator]
static ALLOC: turbo_tasks_malloc::TurboMalloc = turbo_tasks_malloc::TurboMalloc;

pub fn criterion_benchmark(c: &mut Criterion) {
next_build_test::register();

let (options, _dir) = init_bench(
"https://github.com/shadcn-ui/ui.git",
"pnpm i",
Some("apps/www"),
"{\n \"env\": {},\n \"webpack\": {},\n \"eslint\": {\n \"ignoreDuringBuilds\": false\n },\n \"typescript\": {\n \"ignoreBuildErrors\": false,\n \"tsconfigPath\": \"tsconfig.json\"\n },\n \"distDir\": \".next\",\n \"cleanDistDir\": true,\n \"assetPrefix\": \"\",\n \"cacheMaxMemorySize\": 52428800,\n \"configOrigin\": \"next.config.mjs\",\n \"useFileSystemPublicRoutes\": true,\n \"generateBuildId\": null,\n \"generateEtags\": true,\n \"pageExtensions\": [\n \"tsx\",\n \"ts\",\n \"jsx\",\n \"js\"\n ],\n \"poweredByHeader\": true,\n \"compress\": true,\n \"analyticsId\": \"\",\n \"images\": {\n \"deviceSizes\": [\n 640,\n 750,\n 828,\n 1080,\n 1200,\n 1920,\n 2048,\n 3840\n ],\n \"imageSizes\": [\n 16,\n 32,\n 48,\n 64,\n 96,\n 128,\n 256,\n 384\n ],\n \"path\": \"/_next/image\",\n \"loader\": \"default\",\n \"loaderFile\": \"\",\n \"domains\": [],\n \"disableStaticImages\": false,\n \"minimumCacheTTL\": 60,\n \"formats\": [\n \"image/webp\"\n ],\n \"dangerouslyAllowSVG\": false,\n \"contentSecurityPolicy\": \"script-src 'none'; frame-src 'none'; sandbox;\",\n \"contentDispositionType\": \"inline\",\n \"remotePatterns\": [\n {\n \"protocol\": \"https\",\n \"hostname\": \"avatars.githubusercontent.com\"\n },\n {\n \"protocol\": \"https\",\n \"hostname\": \"images.unsplash.com\"\n }\n ],\n \"unoptimized\": false\n },\n \"devIndicators\": {\n \"buildActivity\": true,\n \"buildActivityPosition\": \"bottom-right\"\n },\n \"onDemandEntries\": {\n \"maxInactiveAge\": 3600000,\n \"pagesBufferLength\": 5\n },\n \"amp\": {\n \"canonicalBase\": \"\"\n },\n \"basePath\": \"\",\n \"sassOptions\": {},\n \"trailingSlash\": false,\n \"i18n\": null,\n \"productionBrowserSourceMaps\": false,\n \"optimizeFonts\": true,\n \"excludeDefaultMomentLocales\": true,\n \"serverRuntimeConfig\": {},\n \"publicRuntimeConfig\": {},\n \"reactProductionProfiling\": false,\n \"reactStrictMode\": true,\n \"httpAgentOptions\": {\n \"keepAlive\": true\n },\n \"outputFileTracing\": true,\n \"staticPageGenerationTimeout\": 60,\n \"swcMinify\": true,\n \"modularizeImports\": {\n \"@mui/icons-material\": {\n \"transform\": \"@mui/icons-material/{{member}}\"\n },\n \"lodash\": {\n \"transform\": \"lodash/{{member}}\"\n }\n },\n \"experimental\": {\n \"prerenderEarlyExit\": false,\n \"serverMinification\": true,\n \"serverSourceMaps\": false,\n \"linkNoTouchStart\": false,\n \"caseSensitiveRoutes\": false,\n \"clientRouterFilter\": true,\n \"clientRouterFilterRedirects\": false,\n \"fetchCacheKeyPrefix\": \"\",\n \"middlewarePrefetch\": \"flexible\",\n \"optimisticClientCache\": true,\n \"manualClientBasePath\": false,\n \"cpus\": 9,\n \"memoryBasedWorkersCount\": false,\n \"isrFlushToDisk\": true,\n \"workerThreads\": false,\n \"optimizeCss\": false,\n \"nextScriptWorkers\": false,\n \"scrollRestoration\": false,\n \"externalDir\": false,\n \"disableOptimizedLoading\": false,\n \"gzipSize\": true,\n \"craCompat\": false,\n \"esmExternals\": true,\n \"fullySpecified\": false,\n \"outputFileTracingRoot\": \"/Users/arlyon/Programming/ui\",\n \"swcTraceProfiling\": false,\n \"forceSwcTransforms\": false,\n \"largePageDataBytes\": 128000,\n \"adjustFontFallbacks\": false,\n \"adjustFontFallbacksWithSizeAdjust\": false,\n \"typedRoutes\": false,\n \"instrumentationHook\": false,\n \"bundlePagesExternals\": false,\n \"parallelServerCompiles\": false,\n \"parallelServerBuildTraces\": false,\n \"ppr\": false,\n \"missingSuspenseWithCSRBailout\": true,\n \"optimizeServerReact\": true,\n \"useEarlyImport\": false,\n \"staleTimes\": {\n \"dynamic\": 30,\n \"static\": 300\n },\n \"optimizePackageImports\": [\n \"lucide-react\",\n \"date-fns\",\n \"lodash-es\",\n \"ramda\",\n \"antd\",\n \"react-bootstrap\",\n \"ahooks\",\n \"@ant-design/icons\",\n \"@headlessui/react\",\n \"@headlessui-float/react\",\n \"@heroicons/react/20/solid\",\n \"@heroicons/react/24/solid\",\n \"@heroicons/react/24/outline\",\n \"@visx/visx\",\n \"@tremor/react\",\n \"rxjs\",\n \"@mui/material\",\n \"@mui/icons-material\",\n \"recharts\",\n \"react-use\",\n \"@material-ui/core\",\n \"@material-ui/icons\",\n \"@tabler/icons-react\",\n \"mui-core\",\n \"react-icons/ai\",\n \"react-icons/bi\",\n \"react-icons/bs\",\n \"react-icons/cg\",\n \"react-icons/ci\",\n \"react-icons/di\",\n \"react-icons/fa\",\n \"react-icons/fa6\",\n \"react-icons/fc\",\n \"react-icons/fi\",\n \"react-icons/gi\",\n \"react-icons/go\",\n \"react-icons/gr\",\n \"react-icons/hi\",\n \"react-icons/hi2\",\n \"react-icons/im\",\n \"react-icons/io\",\n \"react-icons/io5\",\n \"react-icons/lia\",\n \"react-icons/lib\",\n \"react-icons/lu\",\n \"react-icons/md\",\n \"react-icons/pi\",\n \"react-icons/ri\",\n \"react-icons/rx\",\n \"react-icons/si\",\n \"react-icons/sl\",\n \"react-icons/tb\",\n \"react-icons/tfi\",\n \"react-icons/ti\",\n \"react-icons/vsc\",\n \"react-icons/wi\"\n ]\n },\n \"configFile\": \"/Users/arlyon/Programming/ui/apps/www/next.config.mjs\",\n \"configFileName\": \"next.config.mjs\",\n \"_originalRedirects\": [\n {\n \"source\": \"/components\",\n \"destination\": \"/docs/components/accordion\",\n \"permanent\": true\n },\n {\n \"source\": \"/docs/components\",\n \"destination\": \"/docs/components/accordion\",\n \"permanent\": true\n },\n {\n \"source\": \"/examples\",\n \"destination\": \"/examples/mail\",\n \"permanent\": false\n },\n {\n \"source\": \"/docs/primitives/:path*\",\n \"destination\": \"/docs/components/:path*\",\n \"permanent\": true\n },\n {\n \"source\": \"/figma\",\n \"destination\": \"/docs/figma\",\n \"permanent\": true\n },\n {\n \"source\": \"/docs/forms\",\n \"destination\": \"/docs/components/form\",\n \"permanent\": false\n },\n {\n \"source\": \"/docs/forms/react-hook-form\",\n \"destination\": \"/docs/components/form\",\n \"permanent\": false\n }\n ],\n \"exportPathMap\": {}\n}"
.to_owned(),
"{\"compilerOptions\":{\"composite\":false,\"declaration\":true,\"declarationMap\":true,\"esModuleInterop\":true,\"forceConsistentCasingInFileNames\":true,\"inlineSources\":false,\"isolatedModules\":true,\"moduleResolution\":2,\"noUnusedLocals\":false,\"noUnusedParameters\":false,\"preserveWatchOutput\":true,\"skipLibCheck\":true,\"strict\":true,\"target\":1,\"lib\":[\"lib.dom.d.ts\",\"lib.dom.iterable.d.ts\",\"lib.esnext.d.ts\"],\"allowJs\":true,\"noEmit\":true,\"incremental\":true,\"module\":99,\"resolveJsonModule\":true,\"jsx\":1,\"baseUrl\":\"/Users/arlyon/Programming/ui/apps/www\",\"paths\":{\"@/*\":[\"./*\"],\"contentlayer/generated\":[\"./.contentlayer/generated\"]},\"plugins\":[{\"name\":\"next\"}],\"pathsBasePath\":\"/Users/arlyon/Programming/ui/apps/www\"}}"
.to_owned(),
);

let rt = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.on_thread_stop(|| {
TurboMalloc::thread_stop();
})
.build()
.unwrap();

c.bench_function("entrypoints", |b| {
b.to_async(&rt).iter(|| {
let options = options.clone();
async move {
let tt = TurboTasks::new(MemoryBackend::new(usize::MAX));
_ = tt
.run_once(async move {
let project = ProjectContainer::new(options.to_owned());
_ = black_box(project.entrypoints().await);
Ok(())
})
.await;
}
});
});

// decide the pages to benchmark ahead of time
const SELECTED_PAGES: [&str; 10] = [
"/legal/event-code-of-conduct",
"/docs/functions/og-image-generation/og-image-api",
"/docs/image-optimization/managing-image-optimization-costs",
"/new/import/card",
"/try/share/[slug]",
"/app-future/[lang]/[teamSlug]/~/account/invoices-new",
"/docs/workflow-collaboration/conformance/rules/NEXTJS_MISSING_REACT_STRICT_MODE",
"/app-future/[lang]/[teamSlug]/~/ai/models/[modelName]/getting-started",
"/app-future/[lang]/[teamSlug]/~/usage/[plan]/[planIteration]",
"/docs/workflow-collaboration/conformance/rules/REQUIRE_CARET_DEPENDENCIES",
];

c.bench_function("10 pages", |b| {
b.to_async(&rt).iter(|| {
let options = options.clone();
async move {
let tt = TurboTasks::new(MemoryBackend::new(usize::MAX));
let result = tt
.run_once(async move {
let project = ProjectContainer::new(options.to_owned());
let entrypoints = project.entrypoints().await.unwrap();
let routes = entrypoints
.routes
.clone()
.into_iter()
.filter(|route| SELECTED_PAGES.contains(&route.0.as_str()));

next_build_test::render_routes(
routes,
next_build_test::Strategy::Concurrent,
10,
10,
)
.await;

Ok(())
})
.await;

black_box(result).unwrap();
}
});
});
}

criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);

0 comments on commit 7ef28f6

Please sign in to comment.