snapshot of https://github.com/tauri-apps/tauri.git (dev, 2026-09-23; blobs > 131072B omitted)
Some checks failed
Audit / audit-js (push) Failing after 0s
bench / bench (map[os:ubuntu-latest runner:xvfb-run --auto-servernum target:x86_64-unknown-linux-gnu], nightly) (push) Failing after 0s
covector version or publish / run-integration-tests (ubuntu-latest) (push) Failing after 0s
Audit / audit-rust (push) Failing after 0s
test `@tauri-apps/cli` / test (ubuntu-latest) (push) Failing after 0s
test `tauri-cli` / test (map[os:ubuntu-latest target:x86_64-unknown-linux-gnu]) (push) Failing after 0s
test core / test (map[args:--all-features key:all], map[cargo:cargo command:test os:ubuntu-latest target:x86_64-unknown-linux-gnu toolchain:1.90]) (push) Failing after 0s
test core / test (map[args:--no-default-features key:no-default], map[cargo:cargo command:test os:ubuntu-latest target:x86_64-unknown-linux-gnu toolchain:1.90]) (push) Failing after 0s
test core / test (map[args:--no-default-features key:no-default], map[cargo:cross command:build os:ubuntu-latest target:aarch64-linux-android toolchain:1.90]) (push) Failing after 0s
deploy schema worker / deploy (push) Failing after 0s
lint rust / clippy (map[cargo:cargo include: os:ubuntu-latest target:x86_64-unknown-linux-gnu]) (push) Failing after 0s
lint rust / clippy (map[cargo:cross include:--package api os:ubuntu-latest target:aarch64-linux-android]) (push) Failing after 0s
supply chain health status / check rust dependencies with cargo vet (push) Failing after 0s
test `@tauri-apps/api` e2e (mobile) / android (push) Failing after 0s
test `@tauri-apps/api` e2e / test (map[name:Linux os:ubuntu-latest]) (push) Failing after 0s
test core / test (map[args:--all-features key:all], map[cargo:cross command:build os:ubuntu-latest target:aarch64-linux-android toolchain:1.90]) (push) Failing after 0s
Udeps / changes (push) Failing after 0s
Udeps / setup (push) Has been skipped
Udeps / udeps (push) Has been skipped
bench / bench (map[os:macos-latest runner: target:aarch64-apple-darwin], nightly) (push) Has been cancelled
bench / bench (map[os:windows-latest runner: target:x86_64-pc-windows-msvc], nightly) (push) Has been cancelled
covector version or publish / run-integration-tests (macos-latest) (push) Has been cancelled
covector version or publish / run-integration-tests (windows-latest) (push) Has been cancelled
covector version or publish / version-or-publish (push) Has been cancelled
test `@tauri-apps/cli` / test (macos-latest) (push) Has been cancelled
test `tauri-cli` / test (map[args:--no-default-features --features native-tls-vendored os:windows-latest restore-only:true target:aarch64-pc-windows-msvc]) (push) Has been cancelled
test `tauri-cli` / test (map[os:macos-latest target:x86_64-apple-darwin]) (push) Has been cancelled
test `tauri-cli` / test (map[os:windows-latest target:x86_64-pc-windows-msvc]) (push) Has been cancelled
test core / test (map[args:--all-features key:all], map[cargo:cargo command:build os:macos-latest target:aarch64-apple-ios toolchain:1.90]) (push) Has been cancelled
test core / test (map[args:--all-features key:all], map[cargo:cargo command:test os:macos-14 target:aarch64-apple-darwin toolchain:1.90]) (push) Has been cancelled
lint rust / clippy (map[cargo:cargo include: os:macos-latest target:aarch64-apple-darwin]) (push) Has been cancelled
lint rust / clippy (map[cargo:cargo include: os:windows-latest target:x86_64-pc-windows-msvc]) (push) Has been cancelled
lint rust / clippy (map[cargo:cargo include:--package api os:macos-latest target:aarch64-apple-ios]) (push) Has been cancelled
test `@tauri-apps/api` e2e (mobile) / ios (push) Has been cancelled
test `@tauri-apps/api` e2e / test (map[name:Windows os:windows-latest]) (push) Has been cancelled
test `@tauri-apps/api` e2e / test (map[name:macOS os:macos-latest]) (push) Has been cancelled
test `@tauri-apps/cli` / test (windows-latest) (push) Has been cancelled
test core / test (map[args:--all-features key:all], map[cargo:cargo command:test os:windows-latest target:x86_64-pc-windows-msvc toolchain:1.90]) (push) Has been cancelled
test core / test (map[args:--no-default-features key:no-default], map[cargo:cargo command:build os:macos-latest target:aarch64-apple-ios toolchain:1.90]) (push) Has been cancelled
test core / test (map[args:--no-default-features key:no-default], map[cargo:cargo command:test os:macos-14 target:aarch64-apple-darwin toolchain:1.90]) (push) Has been cancelled
test core / test (map[args:--no-default-features key:no-default], map[cargo:cargo command:test os:windows-latest target:x86_64-pc-windows-msvc toolchain:1.90]) (push) Has been cancelled
Some checks failed
Audit / audit-js (push) Failing after 0s
bench / bench (map[os:ubuntu-latest runner:xvfb-run --auto-servernum target:x86_64-unknown-linux-gnu], nightly) (push) Failing after 0s
covector version or publish / run-integration-tests (ubuntu-latest) (push) Failing after 0s
Audit / audit-rust (push) Failing after 0s
test `@tauri-apps/cli` / test (ubuntu-latest) (push) Failing after 0s
test `tauri-cli` / test (map[os:ubuntu-latest target:x86_64-unknown-linux-gnu]) (push) Failing after 0s
test core / test (map[args:--all-features key:all], map[cargo:cargo command:test os:ubuntu-latest target:x86_64-unknown-linux-gnu toolchain:1.90]) (push) Failing after 0s
test core / test (map[args:--no-default-features key:no-default], map[cargo:cargo command:test os:ubuntu-latest target:x86_64-unknown-linux-gnu toolchain:1.90]) (push) Failing after 0s
test core / test (map[args:--no-default-features key:no-default], map[cargo:cross command:build os:ubuntu-latest target:aarch64-linux-android toolchain:1.90]) (push) Failing after 0s
deploy schema worker / deploy (push) Failing after 0s
lint rust / clippy (map[cargo:cargo include: os:ubuntu-latest target:x86_64-unknown-linux-gnu]) (push) Failing after 0s
lint rust / clippy (map[cargo:cross include:--package api os:ubuntu-latest target:aarch64-linux-android]) (push) Failing after 0s
supply chain health status / check rust dependencies with cargo vet (push) Failing after 0s
test `@tauri-apps/api` e2e (mobile) / android (push) Failing after 0s
test `@tauri-apps/api` e2e / test (map[name:Linux os:ubuntu-latest]) (push) Failing after 0s
test core / test (map[args:--all-features key:all], map[cargo:cross command:build os:ubuntu-latest target:aarch64-linux-android toolchain:1.90]) (push) Failing after 0s
Udeps / changes (push) Failing after 0s
Udeps / setup (push) Has been skipped
Udeps / udeps (push) Has been skipped
bench / bench (map[os:macos-latest runner: target:aarch64-apple-darwin], nightly) (push) Has been cancelled
bench / bench (map[os:windows-latest runner: target:x86_64-pc-windows-msvc], nightly) (push) Has been cancelled
covector version or publish / run-integration-tests (macos-latest) (push) Has been cancelled
covector version or publish / run-integration-tests (windows-latest) (push) Has been cancelled
covector version or publish / version-or-publish (push) Has been cancelled
test `@tauri-apps/cli` / test (macos-latest) (push) Has been cancelled
test `tauri-cli` / test (map[args:--no-default-features --features native-tls-vendored os:windows-latest restore-only:true target:aarch64-pc-windows-msvc]) (push) Has been cancelled
test `tauri-cli` / test (map[os:macos-latest target:x86_64-apple-darwin]) (push) Has been cancelled
test `tauri-cli` / test (map[os:windows-latest target:x86_64-pc-windows-msvc]) (push) Has been cancelled
test core / test (map[args:--all-features key:all], map[cargo:cargo command:build os:macos-latest target:aarch64-apple-ios toolchain:1.90]) (push) Has been cancelled
test core / test (map[args:--all-features key:all], map[cargo:cargo command:test os:macos-14 target:aarch64-apple-darwin toolchain:1.90]) (push) Has been cancelled
lint rust / clippy (map[cargo:cargo include: os:macos-latest target:aarch64-apple-darwin]) (push) Has been cancelled
lint rust / clippy (map[cargo:cargo include: os:windows-latest target:x86_64-pc-windows-msvc]) (push) Has been cancelled
lint rust / clippy (map[cargo:cargo include:--package api os:macos-latest target:aarch64-apple-ios]) (push) Has been cancelled
test `@tauri-apps/api` e2e (mobile) / ios (push) Has been cancelled
test `@tauri-apps/api` e2e / test (map[name:Windows os:windows-latest]) (push) Has been cancelled
test `@tauri-apps/api` e2e / test (map[name:macOS os:macos-latest]) (push) Has been cancelled
test `@tauri-apps/cli` / test (windows-latest) (push) Has been cancelled
test core / test (map[args:--all-features key:all], map[cargo:cargo command:test os:windows-latest target:x86_64-pc-windows-msvc toolchain:1.90]) (push) Has been cancelled
test core / test (map[args:--no-default-features key:no-default], map[cargo:cargo command:build os:macos-latest target:aarch64-apple-ios toolchain:1.90]) (push) Has been cancelled
test core / test (map[args:--no-default-features key:no-default], map[cargo:cargo command:test os:macos-14 target:aarch64-apple-darwin toolchain:1.90]) (push) Has been cancelled
test core / test (map[args:--no-default-features key:no-default], map[cargo:cargo command:test os:windows-latest target:x86_64-pc-windows-msvc toolchain:1.90]) (push) Has been cancelled
This commit is contained in:
27
bench/Cargo.toml
Normal file
27
bench/Cargo.toml
Normal file
@@ -0,0 +1,27 @@
|
||||
[package]
|
||||
name = "tauri_bench"
|
||||
version = "0.1.0"
|
||||
authors = ["Tauri Programme within The Commons Conservancy"]
|
||||
edition = "2024"
|
||||
rust-version = "1.90"
|
||||
license = "Apache-2.0 OR MIT"
|
||||
description = "Cross-platform WebView rendering library"
|
||||
repository = "https://github.com/tauri-apps/wry"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1"
|
||||
time = { version = "0.3", features = ["formatting"] }
|
||||
tempfile = "3"
|
||||
serde_json = "1"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
|
||||
[[bin]]
|
||||
name = "run_benchmark"
|
||||
path = "src/run_benchmark.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "build_benchmark_jsons"
|
||||
path = "src/build_benchmark_jsons.rs"
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
38
bench/README.md
Normal file
38
bench/README.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# Tauri Bench
|
||||
|
||||
<img align="right" src="https://github.com/tauri-apps/tauri/raw/dev/.github/icon.png" height="128" width="128">
|
||||
|
||||
[](https://github.com/tauri-apps/tauri)
|
||||
[](https://opencollective.com/tauri)
|
||||
[](https://github.com/tauri-apps/tauri/actions/workflows/test-core.yml)
|
||||
[](https://app.fossa.com/projects/git%2Bgithub.com%2Ftauri-apps%2Ftauri?ref=badge_shield)
|
||||
[](https://discord.gg/SpmNs4S)
|
||||
[](https://tauri.app)
|
||||
[](https://good-labs.github.io/greater-good-affirmation)
|
||||
[](https://opencollective.com/tauri)
|
||||
|
||||
## About Tauri
|
||||
|
||||
Tauri is a polyglot and generic system that is very composable and allows engineers to make a wide variety of applications. It is used for building applications for Desktop Computers using a combination of Rust tools and HTML rendered in a Webview. Apps built with Tauri can ship with any number of pieces of an optional JS API / Rust API so that webviews can control the system via message passing. In fact, developers can extend the default API with their own functionality and bridge the Webview and Rust-based backend easily.
|
||||
|
||||
Tauri apps can have custom menus and have tray-type interfaces. They can be updated, and are managed by the user's operating system as expected. They are very small, because they use the system's webview. They do not ship a runtime, since the final binary is compiled from rust. This makes the reversing of Tauri apps not a trivial task.
|
||||
|
||||
## This module
|
||||
|
||||
This rust module run on CI, provides internal metrics results of Tauri. To learn more see [benchmark_results](https://github.com/tauri-apps/benchmark_results) repository.
|
||||
|
||||
**\*_Internal use only_**
|
||||
|
||||
## Semver
|
||||
|
||||
**tauri** is following [Semantic Versioning 2.0](https://semver.org/).
|
||||
|
||||
## Licenses
|
||||
|
||||
Code: (c) 2015 - 2021 - The Tauri Programme within The Commons Conservancy.
|
||||
|
||||
MIT or MIT/Apache 2.0 where applicable.
|
||||
|
||||
Logo: CC-BY-NC-ND
|
||||
|
||||
- Original Tauri Logo Designs by [Daniel Thompson-Yvetot](https://github.com/nothingismagick) and [Guillaume Chau](https://github.com/akryum)
|
||||
69
bench/src/build_benchmark_jsons.rs
Normal file
69
bench/src/build_benchmark_jsons.rs
Normal file
@@ -0,0 +1,69 @@
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//! This Rust binary runs on CI and provides internal metrics results of Tauri. To learn more see [benchmark_results](https://github.com/tauri-apps/benchmark_results) repository.
|
||||
//!
|
||||
//! ***_Internal use only_**
|
||||
|
||||
#![doc(
|
||||
html_logo_url = "https://github.com/tauri-apps/tauri/raw/dev/.github/icon.png",
|
||||
html_favicon_url = "https://github.com/tauri-apps/tauri/raw/dev/.github/icon.png"
|
||||
)]
|
||||
// file is used by multiple binaries
|
||||
#![allow(dead_code)]
|
||||
|
||||
use std::{fs::File, io::BufReader};
|
||||
mod utils;
|
||||
|
||||
fn main() {
|
||||
let platform = if cfg!(target_os = "macos") {
|
||||
"macos"
|
||||
} else if cfg!(target_os = "windows") {
|
||||
"windows"
|
||||
} else {
|
||||
"linux"
|
||||
};
|
||||
let tauri_data = &utils::tauri_root_path()
|
||||
.join("gh-pages")
|
||||
.join(format!("tauri-data-{platform}.json"));
|
||||
let tauri_recent = &utils::tauri_root_path()
|
||||
.join("gh-pages")
|
||||
.join(format!("tauri-recent-{platform}.json"));
|
||||
|
||||
// current data
|
||||
let current_data_buffer = BufReader::new(
|
||||
File::open(utils::target_dir().join("bench.json")).expect("Unable to read current data file"),
|
||||
);
|
||||
let current_data: utils::BenchResult =
|
||||
serde_json::from_reader(current_data_buffer).expect("Unable to read current data buffer");
|
||||
|
||||
// all data's
|
||||
let all_data_buffer =
|
||||
BufReader::new(File::open(tauri_data).expect("Unable to read all data file"));
|
||||
let mut all_data: Vec<utils::BenchResult> =
|
||||
serde_json::from_reader(all_data_buffer).expect("Unable to read all data buffer");
|
||||
|
||||
// add current data to all data
|
||||
all_data.push(current_data);
|
||||
|
||||
// use only latest 20 elements from all data
|
||||
let recent: Vec<utils::BenchResult> = if all_data.len() > 20 {
|
||||
all_data[all_data.len() - 20..].to_vec()
|
||||
} else {
|
||||
all_data.clone()
|
||||
};
|
||||
|
||||
// write json's
|
||||
utils::write_json(
|
||||
tauri_data,
|
||||
&serde_json::to_value(&all_data).expect("Unable to build final json (all)"),
|
||||
)
|
||||
.unwrap_or_else(|_| panic!("Unable to write {}", tauri_data.display()));
|
||||
|
||||
utils::write_json(
|
||||
tauri_recent,
|
||||
&serde_json::to_value(recent).expect("Unable to build final json (recent)"),
|
||||
)
|
||||
.unwrap_or_else(|_| panic!("Unable to write {}", tauri_recent.display()));
|
||||
}
|
||||
394
bench/src/run_benchmark.rs
Normal file
394
bench/src/run_benchmark.rs
Normal file
@@ -0,0 +1,394 @@
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//! This Rust binary runs on CI and provides internal metrics results of Tauri.
|
||||
//! To learn more see [benchmark_results](https://github.com/tauri-apps/benchmark_results) repository.
|
||||
//!
|
||||
//! ***_Internal use only_***
|
||||
|
||||
#![doc(
|
||||
html_logo_url = "https://github.com/tauri-apps/tauri/raw/dev/.github/icon.png",
|
||||
html_favicon_url = "https://github.com/tauri-apps/tauri/raw/dev/.github/icon.png"
|
||||
)]
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use std::{
|
||||
collections::{HashMap, HashSet},
|
||||
env,
|
||||
path::Path,
|
||||
process::{Command, Stdio},
|
||||
};
|
||||
use time::format_description::well_known::Rfc3339;
|
||||
|
||||
mod utils;
|
||||
|
||||
/// The list of examples for benchmarks
|
||||
fn get_all_benchmarks(target: &str) -> Vec<(String, String)> {
|
||||
let extension = if cfg!(windows) { ".exe" } else { "" };
|
||||
vec![
|
||||
(
|
||||
"tauri_hello_world".into(),
|
||||
format!("../target/{target}/release/bench_helloworld{extension}"),
|
||||
),
|
||||
(
|
||||
"tauri_cpu_intensive".into(),
|
||||
format!("../target/{target}/release/bench_cpu_intensive{extension}"),
|
||||
),
|
||||
(
|
||||
"tauri_3mb_transfer".into(),
|
||||
format!("../target/{target}/release/bench_files_transfer{extension}"),
|
||||
),
|
||||
]
|
||||
}
|
||||
|
||||
fn run_strace_benchmarks(new_data: &mut utils::BenchResult, target: &str) -> Result<()> {
|
||||
use std::io::Read;
|
||||
|
||||
let mut thread_count = HashMap::<String, u64>::new();
|
||||
let mut syscall_count = HashMap::<String, u64>::new();
|
||||
|
||||
for (name, example_exe) in get_all_benchmarks(target) {
|
||||
let mut file = tempfile::NamedTempFile::new()
|
||||
.context("failed to create temporary file for strace output")?;
|
||||
|
||||
let exe_path = utils::bench_root_path().join(&example_exe);
|
||||
let exe_path_str = exe_path
|
||||
.to_str()
|
||||
.context("executable path contains invalid UTF-8")?;
|
||||
let temp_path_str = file
|
||||
.path()
|
||||
.to_str()
|
||||
.context("temporary file path contains invalid UTF-8")?;
|
||||
|
||||
Command::new("strace")
|
||||
.args(["-c", "-f", "-o", temp_path_str, exe_path_str])
|
||||
.stdout(Stdio::inherit())
|
||||
.spawn()
|
||||
.context("failed to spawn strace process")?
|
||||
.wait()
|
||||
.context("failed to wait for strace process")?;
|
||||
|
||||
let mut output = String::new();
|
||||
file
|
||||
.as_file_mut()
|
||||
.read_to_string(&mut output)
|
||||
.context("failed to read strace output")?;
|
||||
|
||||
let strace_result = utils::parse_strace_output(&output);
|
||||
// Count clone/clone3 syscalls as thread creation indicators
|
||||
let clone_calls = strace_result.get("clone").map(|d| d.calls).unwrap_or(0)
|
||||
+ strace_result.get("clone3").map(|d| d.calls).unwrap_or(0);
|
||||
|
||||
if let Some(total) = strace_result.get("total") {
|
||||
thread_count.insert(name.clone(), clone_calls);
|
||||
syscall_count.insert(name, total.calls);
|
||||
}
|
||||
}
|
||||
|
||||
new_data.thread_count = thread_count;
|
||||
new_data.syscall_count = syscall_count;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn run_max_mem_benchmark(target: &str) -> Result<HashMap<String, u64>> {
|
||||
let mut results = HashMap::<String, u64>::new();
|
||||
|
||||
for (name, example_exe) in get_all_benchmarks(target) {
|
||||
let benchmark_file = utils::target_dir().join(format!("mprof{name}_.dat"));
|
||||
let benchmark_file_str = benchmark_file
|
||||
.to_str()
|
||||
.context("benchmark file path contains invalid UTF-8")?;
|
||||
|
||||
let exe_path = utils::bench_root_path().join(&example_exe);
|
||||
let exe_path_str = exe_path
|
||||
.to_str()
|
||||
.context("executable path contains invalid UTF-8")?;
|
||||
|
||||
let proc = Command::new("mprof")
|
||||
.args(["run", "-C", "-o", benchmark_file_str, exe_path_str])
|
||||
.stdout(Stdio::null())
|
||||
.stderr(Stdio::piped())
|
||||
.spawn()
|
||||
.with_context(|| format!("failed to spawn mprof for benchmark {name}"))?;
|
||||
|
||||
let proc_result = proc
|
||||
.wait_with_output()
|
||||
.with_context(|| format!("failed to wait for mprof {name}"))?;
|
||||
|
||||
if !proc_result.status.success() {
|
||||
eprintln!(
|
||||
"mprof failed for {name}: {}",
|
||||
String::from_utf8_lossy(&proc_result.stderr)
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(mem) = utils::parse_max_mem(benchmark_file_str)
|
||||
.with_context(|| format!("failed to parse mprof data for {name}"))?
|
||||
{
|
||||
results.insert(name, mem);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(results)
|
||||
}
|
||||
|
||||
fn rlib_size(target_dir: &std::path::Path, library: &str) -> Result<u64> {
|
||||
let prefix = format!("lib{library}");
|
||||
|
||||
let mut size = 0;
|
||||
let mut seen = HashSet::new();
|
||||
|
||||
let build_dir = target_dir.join("build").join(library);
|
||||
for entry in std::fs::read_dir(&build_dir).with_context(|| {
|
||||
format!(
|
||||
"failed to read target build directory: {}",
|
||||
build_dir.display()
|
||||
)
|
||||
})? {
|
||||
let entry = entry.context("failed to read directory entry")?;
|
||||
let out_path = entry.path().join("out");
|
||||
|
||||
for file in std::fs::read_dir(&out_path).with_context(|| {
|
||||
format!(
|
||||
"failed to read target build output directory: {}",
|
||||
out_path.display()
|
||||
)
|
||||
})? {
|
||||
let file = file.context("failed to read build output directory entry")?;
|
||||
let name = file.file_name().to_string_lossy().to_string();
|
||||
if name.starts_with(&prefix) && name.ends_with(".rlib") {
|
||||
let start = name.split('-').next().unwrap();
|
||||
if seen.insert(start.to_string()) {
|
||||
size += file
|
||||
.metadata()
|
||||
.context("failed to read file metadata")?
|
||||
.len();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if size == 0 {
|
||||
anyhow::bail!(
|
||||
"no rlib files found for prefix {prefix} in {}",
|
||||
build_dir.display()
|
||||
);
|
||||
}
|
||||
|
||||
Ok(size)
|
||||
}
|
||||
|
||||
fn get_binary_sizes(target_dir: &Path, target: &str) -> Result<HashMap<String, u64>> {
|
||||
let mut sizes = HashMap::<String, u64>::new();
|
||||
|
||||
let wry_size = rlib_size(target_dir, "wry")?;
|
||||
sizes.insert("wry_rlib".to_string(), wry_size);
|
||||
|
||||
for (name, example_exe) in get_all_benchmarks(target) {
|
||||
let exe_path = utils::bench_root_path().join(&example_exe);
|
||||
let meta = std::fs::metadata(&exe_path)
|
||||
.with_context(|| format!("failed to read metadata for {}", exe_path.display()))?;
|
||||
sizes.insert(name, meta.len());
|
||||
}
|
||||
|
||||
Ok(sizes)
|
||||
}
|
||||
|
||||
/// (target OS, target triple)
|
||||
const TARGETS: &[(&str, &[&str])] = &[
|
||||
(
|
||||
"Windows",
|
||||
&[
|
||||
"x86_64-pc-windows-gnu",
|
||||
"i686-pc-windows-gnu",
|
||||
"i686-pc-windows-msvc",
|
||||
"x86_64-pc-windows-msvc",
|
||||
],
|
||||
),
|
||||
(
|
||||
"Linux",
|
||||
&[
|
||||
"x86_64-unknown-linux-gnu",
|
||||
"i686-unknown-linux-gnu",
|
||||
"aarch64-unknown-linux-gnu",
|
||||
],
|
||||
),
|
||||
("macOS", &["x86_64-apple-darwin", "aarch64-apple-darwin"]),
|
||||
];
|
||||
|
||||
fn cargo_deps() -> HashMap<String, usize> {
|
||||
let mut results = HashMap::new();
|
||||
for (os, targets) in TARGETS {
|
||||
for target in *targets {
|
||||
let mut cmd = Command::new("cargo");
|
||||
cmd.arg("tree");
|
||||
cmd.arg("--no-dedupe");
|
||||
cmd.args(["--edges", "normal"]);
|
||||
cmd.args(["--prefix", "none"]);
|
||||
cmd.args(["--target", target]);
|
||||
cmd.current_dir(utils::tauri_root_path());
|
||||
|
||||
match cmd.output() {
|
||||
Ok(output) if output.status.success() => {
|
||||
let full_deps = String::from_utf8_lossy(&output.stdout);
|
||||
let count = full_deps
|
||||
.lines()
|
||||
.collect::<HashSet<_>>()
|
||||
.len()
|
||||
.saturating_sub(1); // output includes wry itself
|
||||
|
||||
// set the count to the highest count seen for this OS
|
||||
let existing = results.entry(os.to_string()).or_default();
|
||||
*existing = count.max(*existing);
|
||||
|
||||
if count <= 10 {
|
||||
eprintln!("Warning: dependency count for {target} seems low: {count}");
|
||||
}
|
||||
}
|
||||
Ok(output) => {
|
||||
eprintln!(
|
||||
"cargo tree failed for {target}: {}",
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
);
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("Failed to run cargo tree for {target}: {e}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
results
|
||||
}
|
||||
|
||||
const RESULT_KEYS: &[&str] = &["mean", "stddev", "user", "system", "min", "max"];
|
||||
|
||||
fn run_exec_time(target: &str) -> Result<HashMap<String, HashMap<String, f64>>> {
|
||||
let target_dir = utils::target_dir();
|
||||
let benchmark_file = target_dir.join("hyperfine_results.json");
|
||||
let benchmark_file_str = benchmark_file
|
||||
.to_str()
|
||||
.context("benchmark file path contains invalid UTF-8")?;
|
||||
|
||||
let mut command = vec![
|
||||
"hyperfine",
|
||||
"--export-json",
|
||||
benchmark_file_str,
|
||||
"--show-output",
|
||||
"--warmup",
|
||||
"3",
|
||||
// It seems like if we run them back to back,
|
||||
// the execution time will get longer and longer for some reason on macOS and Windows
|
||||
"--prepare",
|
||||
"sleep 1",
|
||||
];
|
||||
|
||||
if cfg!(target_os = "windows") {
|
||||
// For `sleep 1` to work
|
||||
// hyperfine uses cmd by default and it would fail with
|
||||
// 'Input redirection is not supported, exiting the process immediately.'
|
||||
command.push("--shell");
|
||||
command.push("powershell");
|
||||
}
|
||||
|
||||
let benchmarks = get_all_benchmarks(target);
|
||||
let mut benchmark_paths = Vec::new();
|
||||
|
||||
for (_, example_exe) in &benchmarks {
|
||||
let exe_path = utils::bench_root_path().join(example_exe);
|
||||
let exe_path_str = exe_path
|
||||
.to_str()
|
||||
.context("executable path contains invalid UTF-8")?;
|
||||
benchmark_paths.push(exe_path_str.to_string());
|
||||
}
|
||||
|
||||
for path in &benchmark_paths {
|
||||
command.push(path.as_str());
|
||||
}
|
||||
|
||||
utils::run(&command)?;
|
||||
|
||||
let mut results = HashMap::<String, HashMap<String, f64>>::new();
|
||||
let hyperfine_results = utils::read_json(benchmark_file_str)?;
|
||||
|
||||
if let Some(results_array) = hyperfine_results
|
||||
.as_object()
|
||||
.and_then(|obj| obj.get("results"))
|
||||
.and_then(|val| val.as_array())
|
||||
{
|
||||
for ((name, _), data) in benchmarks.iter().zip(results_array.iter()) {
|
||||
if let Some(data_obj) = data.as_object() {
|
||||
let filtered_data: HashMap<String, f64> = data_obj
|
||||
.iter()
|
||||
.filter(|(key, _)| RESULT_KEYS.contains(&key.as_str()))
|
||||
.filter_map(|(key, val)| val.as_f64().map(|v| (key.clone(), v)))
|
||||
.collect();
|
||||
|
||||
results.insert(name.clone(), filtered_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(results)
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let json_3mb = utils::home_path().join(".tauri_3mb.json");
|
||||
|
||||
if !json_3mb.exists() {
|
||||
println!("Downloading test data...");
|
||||
utils::download_file(
|
||||
"https://github.com/lemarier/tauri-test/releases/download/v2.0.0/json_3mb.json",
|
||||
json_3mb,
|
||||
)
|
||||
.context("failed to download test data")?;
|
||||
}
|
||||
|
||||
println!("Starting tauri benchmark");
|
||||
|
||||
let target_dir = utils::target_dir();
|
||||
let target = utils::get_target();
|
||||
|
||||
env::set_current_dir(utils::bench_root_path())
|
||||
.context("failed to set working directory to bench root")?;
|
||||
|
||||
println!("Running execution time benchmarks...");
|
||||
let exec_time = run_exec_time(target)?;
|
||||
|
||||
println!("Getting binary sizes...");
|
||||
let binary_size = get_binary_sizes(&target_dir, target)?;
|
||||
|
||||
println!("Analyzing cargo dependencies...");
|
||||
let cargo_deps = cargo_deps();
|
||||
|
||||
let mut new_data = utils::BenchResult {
|
||||
created_at: time::OffsetDateTime::now_utc().format(&Rfc3339).unwrap(),
|
||||
sha1: {
|
||||
let output = utils::run_collect(&["git", "rev-parse", "HEAD"])?;
|
||||
output.0.trim().to_string()
|
||||
},
|
||||
exec_time,
|
||||
binary_size,
|
||||
cargo_deps,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
if cfg!(target_os = "linux") {
|
||||
println!("Running Linux-specific benchmarks...");
|
||||
run_strace_benchmarks(&mut new_data, target)?;
|
||||
new_data.max_memory = run_max_mem_benchmark(target)?;
|
||||
}
|
||||
|
||||
println!("===== <BENCHMARK RESULTS>");
|
||||
serde_json::to_writer_pretty(std::io::stdout(), &new_data)
|
||||
.context("failed to serialize benchmark results")?;
|
||||
println!("\n===== </BENCHMARK RESULTS>");
|
||||
|
||||
let bench_file = target_dir.join("bench.json");
|
||||
utils::write_json(&bench_file, &serde_json::to_value(&new_data)?)
|
||||
.context("failed to write benchmark results to file")?;
|
||||
println!("Results written to: {}", bench_file.display());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
275
bench/src/utils.rs
Normal file
275
bench/src/utils.rs
Normal file
@@ -0,0 +1,275 @@
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
//! Utility functions for benchmarking tasks in the Tauri project.
|
||||
//!
|
||||
//! This module provides helpers for:
|
||||
//! - Paths to project directories and targets
|
||||
//! - Running and collecting process outputs
|
||||
//! - Parsing memory profiler (`mprof`) and syscall profiler (`strace`) outputs
|
||||
//! - JSON read/write utilities
|
||||
//! - File download utilities (via `curl` or file copy)
|
||||
|
||||
use anyhow::{Context, Result, bail};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
fs,
|
||||
io::{BufRead, BufReader},
|
||||
path::{Path, PathBuf},
|
||||
process::{Command, Output, Stdio},
|
||||
};
|
||||
|
||||
/// Holds the results of a benchmark run.
|
||||
#[derive(Default, Clone, Serialize, Deserialize, Debug)]
|
||||
pub struct BenchResult {
|
||||
pub created_at: String,
|
||||
pub sha1: String,
|
||||
pub exec_time: HashMap<String, HashMap<String, f64>>,
|
||||
pub binary_size: HashMap<String, u64>,
|
||||
pub max_memory: HashMap<String, u64>,
|
||||
pub thread_count: HashMap<String, u64>,
|
||||
pub syscall_count: HashMap<String, u64>,
|
||||
pub cargo_deps: HashMap<String, usize>,
|
||||
}
|
||||
|
||||
/// Represents a single line of parsed `strace` output.
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct StraceOutput {
|
||||
pub percent_time: f64,
|
||||
pub seconds: f64,
|
||||
pub usecs_per_call: Option<u64>,
|
||||
pub calls: u64,
|
||||
pub errors: u64,
|
||||
}
|
||||
|
||||
/// Get the compilation target triple for the current platform.
|
||||
pub fn get_target() -> &'static str {
|
||||
#[cfg(target_os = "macos")]
|
||||
return if cfg!(target_arch = "aarch64") {
|
||||
"aarch64-apple-darwin"
|
||||
} else {
|
||||
"x86_64-apple-darwin"
|
||||
};
|
||||
|
||||
#[cfg(target_os = "ios")]
|
||||
return if cfg!(target_arch = "aarch64") {
|
||||
"aarch64-apple-ios"
|
||||
} else {
|
||||
"x86_64-apple-ios"
|
||||
};
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
return "x86_64-unknown-linux-gnu";
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
return "x86_64-pc-windows-msvc";
|
||||
}
|
||||
|
||||
/// Get the `target/release` directory path for benchmarks.
|
||||
pub fn target_dir() -> PathBuf {
|
||||
bench_root_path()
|
||||
.join("..")
|
||||
.join("target")
|
||||
.join(get_target())
|
||||
.join("release")
|
||||
}
|
||||
|
||||
/// Get the root path of the current benchmark crate.
|
||||
pub fn bench_root_path() -> PathBuf {
|
||||
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
||||
}
|
||||
|
||||
/// Get the home directory of the current user.
|
||||
pub fn home_path() -> PathBuf {
|
||||
#[cfg(any(target_os = "macos", target_os = "ios", target_os = "linux"))]
|
||||
{
|
||||
PathBuf::from(std::env::var("HOME").unwrap_or_default())
|
||||
}
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
PathBuf::from(std::env::var("USERPROFILE").unwrap_or_default())
|
||||
}
|
||||
}
|
||||
|
||||
/// Get the root path of the Tauri repository.
|
||||
pub fn tauri_root_path() -> PathBuf {
|
||||
bench_root_path().parent().map(|p| p.to_path_buf()).unwrap()
|
||||
}
|
||||
|
||||
/// Run a command and collect its stdout and stderr as strings.
|
||||
/// Returns an error if the command fails or exits with a non-zero status.
|
||||
pub fn run_collect(cmd: &[&str]) -> Result<(String, String)> {
|
||||
let output: Output = Command::new(cmd[0])
|
||||
.args(&cmd[1..])
|
||||
.stdin(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.output()
|
||||
.with_context(|| format!("failed to execute command: {cmd:?}"))?;
|
||||
|
||||
if !output.status.success() {
|
||||
bail!(
|
||||
"Command {:?} exited with {:?}\nstdout:\n{}\nstderr:\n{}",
|
||||
cmd,
|
||||
output.status.code(),
|
||||
String::from_utf8_lossy(&output.stdout),
|
||||
String::from_utf8_lossy(&output.stderr)
|
||||
);
|
||||
}
|
||||
|
||||
Ok((
|
||||
String::from_utf8_lossy(&output.stdout).to_string(),
|
||||
String::from_utf8_lossy(&output.stderr).to_string(),
|
||||
))
|
||||
}
|
||||
|
||||
/// Parse a memory profiler (`mprof`) output file and return the maximum
|
||||
/// memory usage in bytes. Returns `None` if no values are found.
|
||||
pub fn parse_max_mem(file_path: &str) -> Result<Option<u64>> {
|
||||
let file = fs::File::open(file_path)
|
||||
.with_context(|| format!("failed to open mprof output file {file_path}"))?;
|
||||
let output = BufReader::new(file);
|
||||
|
||||
let mut highest: u64 = 0;
|
||||
|
||||
for line in output.lines().map_while(Result::ok) {
|
||||
let split: Vec<&str> = line.split(' ').collect();
|
||||
if split.len() == 3 {
|
||||
if let Ok(mb) = split[1].parse::<f64>() {
|
||||
let current_bytes = (mb * 1024.0 * 1024.0) as u64;
|
||||
highest = highest.max(current_bytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Best-effort cleanup
|
||||
let _ = fs::remove_file(file_path);
|
||||
|
||||
Ok(if highest > 0 { Some(highest) } else { None })
|
||||
}
|
||||
|
||||
/// Parse the output of `strace -c` and return a summary of syscalls.
|
||||
pub fn parse_strace_output(output: &str) -> HashMap<String, StraceOutput> {
|
||||
let mut summary = HashMap::new();
|
||||
|
||||
let mut lines = output
|
||||
.lines()
|
||||
.filter(|line| !line.is_empty() && !line.contains("detached ..."));
|
||||
|
||||
let count = lines.clone().count();
|
||||
if count < 4 {
|
||||
return summary;
|
||||
}
|
||||
|
||||
let total_line = lines.next_back().unwrap();
|
||||
lines.next_back(); // Drop separator
|
||||
let data_lines = lines.skip(2);
|
||||
|
||||
for line in data_lines {
|
||||
let syscall_fields: Vec<&str> = line.split_whitespace().collect();
|
||||
let len = syscall_fields.len();
|
||||
|
||||
if let Some(&syscall_name) = syscall_fields.last() {
|
||||
if (5..=6).contains(&len) {
|
||||
let output = StraceOutput {
|
||||
percent_time: syscall_fields[0].parse().unwrap_or(0.0),
|
||||
seconds: syscall_fields[1].parse().unwrap_or(0.0),
|
||||
usecs_per_call: syscall_fields[2].parse().ok(),
|
||||
calls: syscall_fields[3].parse().unwrap_or(0),
|
||||
errors: if len < 6 {
|
||||
0
|
||||
} else {
|
||||
syscall_fields[4].parse().unwrap_or(0)
|
||||
},
|
||||
};
|
||||
summary.insert(syscall_name.to_string(), output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let total_fields: Vec<&str> = total_line.split_whitespace().collect();
|
||||
let total = match total_fields.len() {
|
||||
5 => StraceOutput {
|
||||
percent_time: total_fields[0].parse().unwrap_or(0.0),
|
||||
seconds: total_fields[1].parse().unwrap_or(0.0),
|
||||
usecs_per_call: None,
|
||||
calls: total_fields[2].parse().unwrap_or(0),
|
||||
errors: total_fields[3].parse().unwrap_or(0),
|
||||
},
|
||||
6 => StraceOutput {
|
||||
percent_time: total_fields[0].parse().unwrap_or(0.0),
|
||||
seconds: total_fields[1].parse().unwrap_or(0.0),
|
||||
usecs_per_call: total_fields[2].parse().ok(),
|
||||
calls: total_fields[3].parse().unwrap_or(0),
|
||||
errors: total_fields[4].parse().unwrap_or(0),
|
||||
},
|
||||
_ => {
|
||||
panic!("Unexpected total field count: {}", total_fields.len());
|
||||
}
|
||||
};
|
||||
|
||||
summary.insert("total".to_string(), total);
|
||||
summary
|
||||
}
|
||||
|
||||
/// Run a command and wait for completion.
|
||||
/// Returns an error if the command fails.
|
||||
pub fn run(cmd: &[&str]) -> Result<()> {
|
||||
let status = Command::new(cmd[0])
|
||||
.args(&cmd[1..])
|
||||
.stdin(Stdio::piped())
|
||||
.status()
|
||||
.with_context(|| format!("failed to execute command: {cmd:?}"))?;
|
||||
|
||||
if !status.success() {
|
||||
bail!("Command {:?} exited with {:?}", cmd, status.code());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Read a JSON file into a [`serde_json::Value`].
|
||||
pub fn read_json(filename: &str) -> Result<Value> {
|
||||
let f =
|
||||
fs::File::open(filename).with_context(|| format!("failed to open JSON file {filename}"))?;
|
||||
Ok(serde_json::from_reader(f)?)
|
||||
}
|
||||
|
||||
/// Write a [`serde_json::Value`] into a JSON file.
|
||||
pub fn write_json(filename: &Path, value: &Value) -> Result<()> {
|
||||
let f = fs::File::create(filename)
|
||||
.with_context(|| format!("failed to create JSON file {}", filename.display()))?;
|
||||
serde_json::to_writer(f, value)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Download a file from either a local path or an HTTP/HTTPS URL.
|
||||
/// Falls back to copying the file if the URL does not start with http/https.
|
||||
pub fn download_file(url: &str, filename: PathBuf) -> Result<()> {
|
||||
if !url.starts_with("http:") && !url.starts_with("https:") {
|
||||
fs::copy(url, &filename).with_context(|| format!("failed to copy from {url}"))?;
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
println!("Downloading {url}");
|
||||
let status = Command::new("curl")
|
||||
.arg("-L")
|
||||
.arg("-s")
|
||||
.arg("-o")
|
||||
.arg(&filename)
|
||||
.arg(url)
|
||||
.status()
|
||||
.with_context(|| format!("failed to execute curl for {url}"))?;
|
||||
|
||||
if !status.success() {
|
||||
bail!("curl failed with exit code {:?}", status.code());
|
||||
}
|
||||
if !filename.exists() {
|
||||
bail!("expected file {:?} to exist after download", filename);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
8
bench/tests/cpu_intensive/public/index.css
Normal file
8
bench/tests/cpu_intensive/public/index.css
Normal file
@@ -0,0 +1,8 @@
|
||||
body {
|
||||
font-family:
|
||||
-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial,
|
||||
sans-serif;
|
||||
margin: auto;
|
||||
max-width: 38rem;
|
||||
padding: 2rem;
|
||||
}
|
||||
16
bench/tests/cpu_intensive/public/index.html
Normal file
16
bench/tests/cpu_intensive/public/index.html
Normal file
@@ -0,0 +1,16 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Hello World!</title>
|
||||
<link rel="stylesheet" href="index.css" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Calculate prime numbers</h1>
|
||||
<p></p>
|
||||
<button type="button" id="start">Start</button>
|
||||
<p id="status"></p>
|
||||
<p id="results"></p>
|
||||
<script src="site.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
57
bench/tests/cpu_intensive/public/site.js
Normal file
57
bench/tests/cpu_intensive/public/site.js
Normal file
@@ -0,0 +1,57 @@
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// Create web worker
|
||||
const THRESHOLD = 10000000
|
||||
const worker = new Worker('worker.js')
|
||||
/** @type {HTMLButtonElement} */
|
||||
const start = document.getElementById('start')
|
||||
/** @type {HTMLParagraphElement} */
|
||||
const status = document.getElementById('status')
|
||||
const results = document.getElementById('results')
|
||||
|
||||
const ITERATIONS = 1
|
||||
|
||||
let resolver
|
||||
|
||||
const onMessage = (message) => {
|
||||
// Update the UI
|
||||
let prefix = '[Calculating]'
|
||||
|
||||
if (message.data.status === 'done') {
|
||||
// tell tauri that we are done
|
||||
window.__TAURI__.core.invoke('app_completed_successfully')
|
||||
}
|
||||
|
||||
status.innerHTML = `${prefix} Found <code>${message.data.count}</code> prime numbers in <code>${message.data.time}ms</code>`
|
||||
|
||||
if (message.data.status === 'done') {
|
||||
resolver(message.data.time)
|
||||
}
|
||||
}
|
||||
|
||||
worker.addEventListener('message', onMessage)
|
||||
|
||||
const benchmark = () => {
|
||||
return new Promise((resolve) => {
|
||||
const startTime = Date.now()
|
||||
resolver = resolve
|
||||
worker.postMessage({ value: THRESHOLD, startTime })
|
||||
})
|
||||
}
|
||||
|
||||
const calculate = async () => {
|
||||
let total = 0
|
||||
|
||||
for (let i = 0; i < ITERATIONS; i++) {
|
||||
const result = await benchmark()
|
||||
total += result
|
||||
}
|
||||
|
||||
const average = total / ITERATIONS
|
||||
|
||||
results.innerText = `Average time: ${average}ms`
|
||||
}
|
||||
|
||||
window.addEventListener('DOMContentLoaded', calculate)
|
||||
49
bench/tests/cpu_intensive/public/worker.js
Normal file
49
bench/tests/cpu_intensive/public/worker.js
Normal file
@@ -0,0 +1,49 @@
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
const isPrime = (number) => {
|
||||
if (number % 2 === 0 && number > 2) {
|
||||
return false
|
||||
}
|
||||
|
||||
let start = 2
|
||||
const limit = Math.sqrt(number)
|
||||
while (start <= limit) {
|
||||
if (number % start++ < 1) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return number > 1
|
||||
}
|
||||
|
||||
addEventListener('message', (e) => {
|
||||
const { startTime } = e.data
|
||||
|
||||
let n = 0
|
||||
let total = 0
|
||||
const THRESHOLD = e.data.value
|
||||
const primes = []
|
||||
|
||||
let previous = startTime
|
||||
|
||||
while (++n <= THRESHOLD) {
|
||||
if (isPrime(n)) {
|
||||
primes.push(n)
|
||||
total++
|
||||
|
||||
const now = Date.now()
|
||||
|
||||
if (now - previous > 250) {
|
||||
previous = now
|
||||
postMessage({
|
||||
status: 'calculating',
|
||||
count: total,
|
||||
time: Date.now() - startTime
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
postMessage({ status: 'done', count: total, time: Date.now() - startTime })
|
||||
})
|
||||
3
bench/tests/cpu_intensive/src-tauri/.gitignore
vendored
Normal file
3
bench/tests/cpu_intensive/src-tauri/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
/target/
|
||||
19
bench/tests/cpu_intensive/src-tauri/Cargo.toml
Normal file
19
bench/tests/cpu_intensive/src-tauri/Cargo.toml
Normal file
@@ -0,0 +1,19 @@
|
||||
[package]
|
||||
name = "bench_cpu_intensive"
|
||||
version = "0.1.0"
|
||||
description = "A very simple Tauri Application"
|
||||
edition = "2024"
|
||||
rust-version = "1.90"
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { workspace = true, default-features = true, features = [
|
||||
"codegen",
|
||||
] }
|
||||
|
||||
[dependencies]
|
||||
serde_json = "1"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
tauri = { workspace = true, default-features = true }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
7
bench/tests/cpu_intensive/src-tauri/build.rs
Normal file
7
bench/tests/cpu_intensive/src-tauri/build.rs
Normal file
@@ -0,0 +1,7 @@
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
fn main() {
|
||||
tauri_build::build()
|
||||
}
|
||||
18
bench/tests/cpu_intensive/src-tauri/src/main.rs
Normal file
18
bench/tests/cpu_intensive/src-tauri/src/main.rs
Normal file
@@ -0,0 +1,18 @@
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// The benchmark can't use this or we can't measure the command time
|
||||
// #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
|
||||
#[tauri::command]
|
||||
fn app_completed_successfully() {
|
||||
std::process::exit(0);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
tauri::Builder::default()
|
||||
.invoke_handler(tauri::generate_handler![app_completed_successfully])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
}
|
||||
31
bench/tests/cpu_intensive/src-tauri/tauri.conf.json
Normal file
31
bench/tests/cpu_intensive/src-tauri/tauri.conf.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"$schema": "../../../../crates/tauri-schema-generator/schemas/config.schema.json",
|
||||
"identifier": "com.tauri.dev",
|
||||
"build": {
|
||||
"frontendDist": "../public"
|
||||
},
|
||||
"app": {
|
||||
"withGlobalTauri": true,
|
||||
"windows": [
|
||||
{
|
||||
"title": "Welcome to Tauri!",
|
||||
"width": 800,
|
||||
"height": 600
|
||||
}
|
||||
],
|
||||
"security": {
|
||||
"csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self'; connect-src ipc: http://ipc.localhost"
|
||||
}
|
||||
},
|
||||
"bundle": {
|
||||
"active": true,
|
||||
"targets": "all",
|
||||
"icon": [
|
||||
"../../../../examples/.icons/32x32.png",
|
||||
"../../../../examples/.icons/128x128.png",
|
||||
"../../../../examples/.icons/128x128@2x.png",
|
||||
"../../../../examples/.icons/icon.icns",
|
||||
"../../../../examples/.icons/icon.ico"
|
||||
]
|
||||
}
|
||||
}
|
||||
30
bench/tests/files_transfer/public/index.html
Normal file
30
bench/tests/files_transfer/public/index.html
Normal file
@@ -0,0 +1,30 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Welcome to Tauri!</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Welcome to Tauri!</h1>
|
||||
|
||||
<script>
|
||||
window.addEventListener('DOMContentLoaded', (event) => {
|
||||
window.__TAURI__.core
|
||||
.invoke('read_file')
|
||||
.then((_data) => {
|
||||
// success
|
||||
window.__TAURI__.core.invoke('app_should_close', {
|
||||
exitCode: 0
|
||||
})
|
||||
})
|
||||
.catch((_error) => {
|
||||
// error
|
||||
window.__TAURI__.core.invoke('app_should_close', {
|
||||
exitCode: 1
|
||||
})
|
||||
})
|
||||
})
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
3
bench/tests/files_transfer/src-tauri/.gitignore
vendored
Normal file
3
bench/tests/files_transfer/src-tauri/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
/target/
|
||||
19
bench/tests/files_transfer/src-tauri/Cargo.toml
Normal file
19
bench/tests/files_transfer/src-tauri/Cargo.toml
Normal file
@@ -0,0 +1,19 @@
|
||||
[package]
|
||||
name = "bench_files_transfer"
|
||||
version = "0.1.0"
|
||||
description = "A very simple Tauri Application"
|
||||
edition = "2024"
|
||||
rust-version = "1.90"
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { workspace = true, default-features = true, features = [
|
||||
"codegen",
|
||||
] }
|
||||
|
||||
[dependencies]
|
||||
serde_json = "1"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
tauri = { workspace = true, default-features = true }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
7
bench/tests/files_transfer/src-tauri/build.rs
Normal file
7
bench/tests/files_transfer/src-tauri/build.rs
Normal file
@@ -0,0 +1,7 @@
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
fn main() {
|
||||
tauri_build::build()
|
||||
}
|
||||
31
bench/tests/files_transfer/src-tauri/src/main.rs
Normal file
31
bench/tests/files_transfer/src-tauri/src/main.rs
Normal file
@@ -0,0 +1,31 @@
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// The benchmark can't use this or we can't measure the command time
|
||||
// #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
|
||||
use std::fs::read;
|
||||
use tauri::{AppHandle, Manager, Runtime, command, ipc::Response, path::BaseDirectory};
|
||||
|
||||
#[command]
|
||||
fn app_should_close(exit_code: i32) {
|
||||
std::process::exit(exit_code);
|
||||
}
|
||||
|
||||
#[command]
|
||||
async fn read_file<R: Runtime>(app: AppHandle<R>) -> Result<Response, String> {
|
||||
let path = app
|
||||
.path()
|
||||
.resolve(".tauri_3mb.json", BaseDirectory::Home)
|
||||
.map_err(|e| e.to_string())?;
|
||||
let contents = read(path).map_err(|e| e.to_string())?;
|
||||
Ok(Response::new(contents))
|
||||
}
|
||||
|
||||
fn main() {
|
||||
tauri::Builder::default()
|
||||
.invoke_handler(tauri::generate_handler![app_should_close, read_file])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
}
|
||||
31
bench/tests/files_transfer/src-tauri/tauri.conf.json
Normal file
31
bench/tests/files_transfer/src-tauri/tauri.conf.json
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"$schema": "../../../../crates/tauri-schema-generator/schemas/config.schema.json",
|
||||
"identifier": "com.tauri.dev",
|
||||
"build": {
|
||||
"frontendDist": "../public"
|
||||
},
|
||||
"app": {
|
||||
"withGlobalTauri": true,
|
||||
"windows": [
|
||||
{
|
||||
"title": "Welcome to Tauri!",
|
||||
"width": 800,
|
||||
"height": 600
|
||||
}
|
||||
],
|
||||
"security": {
|
||||
"csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self'; connect-src ipc: http://ipc.localhost"
|
||||
}
|
||||
},
|
||||
"bundle": {
|
||||
"active": true,
|
||||
"targets": "all",
|
||||
"icon": [
|
||||
"../../../../examples/.icons/32x32.png",
|
||||
"../../../../examples/.icons/128x128.png",
|
||||
"../../../../examples/.icons/128x128@2x.png",
|
||||
"../../../../examples/.icons/icon.icns",
|
||||
"../../../../examples/.icons/icon.ico"
|
||||
]
|
||||
}
|
||||
}
|
||||
17
bench/tests/helloworld/public/index.html
Normal file
17
bench/tests/helloworld/public/index.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Welcome to Tauri!</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Welcome to Tauri!</h1>
|
||||
|
||||
<script>
|
||||
window.addEventListener('DOMContentLoaded', (event) =>
|
||||
window.__TAURI__.core.invoke('app_loaded_successfully')
|
||||
)
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
3
bench/tests/helloworld/src-tauri/.gitignore
vendored
Normal file
3
bench/tests/helloworld/src-tauri/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# Generated by Cargo
|
||||
# will have compiled files and executables
|
||||
/target/
|
||||
19
bench/tests/helloworld/src-tauri/Cargo.toml
Normal file
19
bench/tests/helloworld/src-tauri/Cargo.toml
Normal file
@@ -0,0 +1,19 @@
|
||||
[package]
|
||||
name = "bench_helloworld"
|
||||
version = "0.1.0"
|
||||
description = "A very simple Tauri Application"
|
||||
edition = "2024"
|
||||
rust-version = "1.90"
|
||||
|
||||
[build-dependencies]
|
||||
tauri-build = { workspace = true, default-features = true, features = [
|
||||
"codegen",
|
||||
] }
|
||||
|
||||
[dependencies]
|
||||
serde_json = "1"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
tauri = { workspace = true, default-features = true }
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
7
bench/tests/helloworld/src-tauri/build.rs
Normal file
7
bench/tests/helloworld/src-tauri/build.rs
Normal file
@@ -0,0 +1,7 @@
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
fn main() {
|
||||
tauri_build::build()
|
||||
}
|
||||
18
bench/tests/helloworld/src-tauri/src/main.rs
Normal file
18
bench/tests/helloworld/src-tauri/src/main.rs
Normal file
@@ -0,0 +1,18 @@
|
||||
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
// The benchmark can't use this or we can't measure the command time
|
||||
// #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
|
||||
#[tauri::command]
|
||||
fn app_loaded_successfully() {
|
||||
std::process::exit(0);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
tauri::Builder::default()
|
||||
.invoke_handler(tauri::generate_handler![app_loaded_successfully])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
}
|
||||
33
bench/tests/helloworld/src-tauri/tauri.conf.json
Normal file
33
bench/tests/helloworld/src-tauri/tauri.conf.json
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"$schema": "../../../../crates/tauri-schema-generator/schemas/config.schema.json",
|
||||
"identifier": "com.tauri.dev",
|
||||
"build": {
|
||||
"frontendDist": "../public",
|
||||
"beforeDevCommand": "",
|
||||
"beforeBuildCommand": ""
|
||||
},
|
||||
"app": {
|
||||
"withGlobalTauri": true,
|
||||
"windows": [
|
||||
{
|
||||
"title": "Welcome to Tauri!",
|
||||
"width": 800,
|
||||
"height": 600
|
||||
}
|
||||
],
|
||||
"security": {
|
||||
"csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self'; connect-src ipc: http://ipc.localhost"
|
||||
}
|
||||
},
|
||||
"bundle": {
|
||||
"active": true,
|
||||
"targets": "all",
|
||||
"icon": [
|
||||
"../../../../examples/.icons/32x32.png",
|
||||
"../../../../examples/.icons/128x128.png",
|
||||
"../../../../examples/.icons/128x128@2x.png",
|
||||
"../../../../examples/.icons/icon.icns",
|
||||
"../../../../examples/.icons/icon.ico"
|
||||
]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user