mirror of
https://github.com/godotengine/godot-benchmarks.git
synced 2026-09-03 18:14:28 +03:00
Style: Unify formatting, add .editorconfig (#88)
This commit is contained in:
23
.editorconfig
Normal file
23
.editorconfig
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
|
indent_size = 4
|
||||||
|
indent_style = tab
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.{csproj,sln}]
|
||||||
|
charset = utf-8-bom
|
||||||
|
end_of_line = crlf
|
||||||
|
|
||||||
|
[*.{cs,py}]
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
[*.{csproj,yml,yaml}]
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
trim_trailing_whitespace = false
|
||||||
7
.gitattributes
vendored
7
.gitattributes
vendored
@@ -1 +1,8 @@
|
|||||||
|
# Properly detect languages on Github
|
||||||
web/static/thirdparty/* linguist-vendored
|
web/static/thirdparty/* linguist-vendored
|
||||||
|
|
||||||
|
# Normalize EOL for all files that Git considers text files
|
||||||
|
* text=auto eol=lf
|
||||||
|
# Except for Visual Studio files
|
||||||
|
*.sln eol=crlf
|
||||||
|
*.csproj eol=crlf
|
||||||
|
|||||||
32
.gitignore
vendored
32
.gitignore
vendored
@@ -16,5 +16,35 @@ mono_crash.*.json
|
|||||||
.directory
|
.directory
|
||||||
*~
|
*~
|
||||||
|
|
||||||
|
# IDE-specific ignores
|
||||||
|
.fleet/
|
||||||
|
.history/
|
||||||
|
.idea/
|
||||||
|
.vs/
|
||||||
|
.vscode/
|
||||||
|
*.code-workspace
|
||||||
|
|
||||||
|
# Python-specific ignores
|
||||||
|
__pycache__/
|
||||||
|
*_cache/
|
||||||
|
*.pyc
|
||||||
|
.venv
|
||||||
|
venv
|
||||||
|
|
||||||
# Godot Git repository clone (run-benchmarks.sh)
|
# Godot Git repository clone (run-benchmarks.sh)
|
||||||
/godot/
|
godot/
|
||||||
|
|
||||||
|
# Output HTML files
|
||||||
|
web/public/
|
||||||
|
|
||||||
|
# Temporary lock file while building
|
||||||
|
web/.hugo_build.lock
|
||||||
|
|
||||||
|
# Generated files
|
||||||
|
web/content/benchmark/*.md
|
||||||
|
web/content/graph/*.md
|
||||||
|
web/data/data.json
|
||||||
|
|
||||||
|
# Untracked source files
|
||||||
|
web/src-data/benchmarks/*.json
|
||||||
|
web/src-data/benchmarks/*.md
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<Project Sdk="Godot.NET.Sdk/4.3.0-dev.2">
|
<Project Sdk="Godot.NET.Sdk/4.3.0-dev.2">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
<TargetFramework Condition=" '$(GodotTargetPlatform)' == 'android' ">net7.0</TargetFramework>
|
<TargetFramework Condition=" '$(GodotTargetPlatform)' == 'android' ">net7.0</TargetFramework>
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
|
||||||
# Visual Studio 2012
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.10.35027.167
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Godot Benchmarks", "Godot Benchmarks.csproj", "{A7FD1DC6-AE2B-4F17-B4BA-2FD940E01B47}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Godot Benchmarks", "Godot Benchmarks.csproj", "{A7FD1DC6-AE2B-4F17-B4BA-2FD940E01B47}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
ExportDebug|Any CPU = ExportDebug|Any CPU
|
ExportDebug|Any CPU = ExportDebug|Any CPU
|
||||||
ExportRelease|Any CPU = ExportRelease|Any CPU
|
ExportRelease|Any CPU = ExportRelease|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{A7FD1DC6-AE2B-4F17-B4BA-2FD940E01B47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{A7FD1DC6-AE2B-4F17-B4BA-2FD940E01B47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
@@ -16,4 +19,10 @@ Global
|
|||||||
{A7FD1DC6-AE2B-4F17-B4BA-2FD940E01B47}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU
|
{A7FD1DC6-AE2B-4F17-B4BA-2FD940E01B47}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU
|
||||||
{A7FD1DC6-AE2B-4F17-B4BA-2FD940E01B47}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU
|
{A7FD1DC6-AE2B-4F17-B4BA-2FD940E01B47}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {0C32B76F-38AD-4A1A-80F4-46FFBBB4BFB2}
|
||||||
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|||||||
@@ -20,19 +20,19 @@ export DISPLAY=":0"
|
|||||||
ARG1="${1:-''}"
|
ARG1="${1:-''}"
|
||||||
|
|
||||||
if ! command -v git &> /dev/null; then
|
if ! command -v git &> /dev/null; then
|
||||||
echo "ERROR: git must be installed and in PATH."
|
echo "ERROR: git must be installed and in PATH."
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "$ARG1" == "--help" || "$ARG1" == "-h" ]]; then
|
if [[ "$ARG1" == "--help" || "$ARG1" == "-h" ]]; then
|
||||||
echo "Usage: $0 [--skip-build]"
|
echo "Usage: $0 [--skip-build]"
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
|
|
||||||
GODOT_REPO_DIR="$DIR/godot"
|
GODOT_REPO_DIR="$DIR/godot"
|
||||||
|
|
||||||
if [[ ! -d "$GODOT_REPO_DIR/.git" ]]; then
|
if [[ ! -d "$GODOT_REPO_DIR/.git" ]]; then
|
||||||
git clone https://github.com/godotengine/godot.git "$GODOT_REPO_DIR"
|
git clone https://github.com/godotengine/godot.git "$GODOT_REPO_DIR"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
pushd "$GODOT_REPO_DIR"
|
pushd "$GODOT_REPO_DIR"
|
||||||
@@ -48,64 +48,64 @@ latest_commit="$(git -C "$GODOT_REPO_DIR" rev-parse HEAD)"
|
|||||||
|
|
||||||
pushd /tmp/godot-benchmarks-results/
|
pushd /tmp/godot-benchmarks-results/
|
||||||
for result in 2*.md; do
|
for result in 2*.md; do
|
||||||
if [[ "${result:11:9}" == "${latest_commit:0:9}" ]]; then
|
if [[ "${result:11:9}" == "${latest_commit:0:9}" ]]; then
|
||||||
echo "godot-benchmarks: Skipping benchmark run as the latest Godot commit is already present in the results repository."
|
echo "godot-benchmarks: Skipping benchmark run as the latest Godot commit is already present in the results repository."
|
||||||
exit
|
exit
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
popd
|
popd
|
||||||
|
|
||||||
GODOT_EMPTY_PROJECT_DIR="$DIR/web/godot-empty-project"
|
GODOT_EMPTY_PROJECT_DIR="$DIR/web/godot-empty-project"
|
||||||
|
|
||||||
if [[ "$ARG1" != "--skip-build" ]]; then
|
if [[ "$ARG1" != "--skip-build" ]]; then
|
||||||
cd "$GODOT_REPO_DIR"
|
cd "$GODOT_REPO_DIR"
|
||||||
|
|
||||||
if command -v ccache &> /dev/null; then
|
if command -v ccache &> /dev/null; then
|
||||||
# Clear ccache to avoid skewing the build time results.
|
# Clear ccache to avoid skewing the build time results.
|
||||||
ccache --clear
|
ccache --clear
|
||||||
fi
|
fi
|
||||||
touch .gdignore
|
touch .gdignore
|
||||||
|
|
||||||
# Measure clean build times for debug and release builds (in milliseconds).
|
# Measure clean build times for debug and release builds (in milliseconds).
|
||||||
# Also create a `.gdignore` file to prevent Godot from importing resources
|
# Also create a `.gdignore` file to prevent Godot from importing resources
|
||||||
# within the Godot Git clone.
|
# within the Godot Git clone.
|
||||||
# WARNING: Any untracked and ignored files included in the repository will be removed!
|
# WARNING: Any untracked and ignored files included in the repository will be removed!
|
||||||
BEGIN="$(date +%s%3N)"
|
BEGIN="$(date +%s%3N)"
|
||||||
PEAK_MEMORY_BUILD_DEBUG=$( (/usr/bin/time -f "%M" scons platform=linuxbsd target=editor optimize=debug module_mono_enabled=no progress=no debug_symbols=yes -j$(nproc) 2>&1 || true) | tail -1)
|
PEAK_MEMORY_BUILD_DEBUG=$( (/usr/bin/time -f "%M" scons platform=linuxbsd target=editor optimize=debug module_mono_enabled=no progress=no debug_symbols=yes -j$(nproc) 2>&1 || true) | tail -1)
|
||||||
END="$(date +%s%3N)"
|
END="$(date +%s%3N)"
|
||||||
TIME_TO_BUILD_DEBUG="$((END - BEGIN))"
|
TIME_TO_BUILD_DEBUG="$((END - BEGIN))"
|
||||||
|
|
||||||
git clean -qdfx --exclude bin
|
git clean -qdfx --exclude bin
|
||||||
if command -v ccache &> /dev/null; then
|
if command -v ccache &> /dev/null; then
|
||||||
# Clear ccache to avoid skewing the build time results.
|
# Clear ccache to avoid skewing the build time results.
|
||||||
ccache --clear
|
ccache --clear
|
||||||
fi
|
fi
|
||||||
touch .gdignore
|
touch .gdignore
|
||||||
|
|
||||||
BEGIN="$(date +%s%3N)"
|
BEGIN="$(date +%s%3N)"
|
||||||
PEAK_MEMORY_BUILD_RELEASE=$( (/usr/bin/time -f "%M" scons platform=linuxbsd target=template_release optimize=speed lto=full module_mono_enabled=no progress=no debug_symbols=yes -j$(nproc) 2>&1 || true) | tail -1)
|
PEAK_MEMORY_BUILD_RELEASE=$( (/usr/bin/time -f "%M" scons platform=linuxbsd target=template_release optimize=speed lto=full module_mono_enabled=no progress=no debug_symbols=yes -j$(nproc) 2>&1 || true) | tail -1)
|
||||||
END="$(date +%s%3N)"
|
END="$(date +%s%3N)"
|
||||||
TIME_TO_BUILD_RELEASE="$((END - BEGIN))"
|
TIME_TO_BUILD_RELEASE="$((END - BEGIN))"
|
||||||
|
|
||||||
# FIXME: C# is disabled because the engine crashes on exit after running benchmarks.
|
# FIXME: C# is disabled because the engine crashes on exit after running benchmarks.
|
||||||
#
|
#
|
||||||
# Generate Mono glue for C# build to work.
|
# Generate Mono glue for C# build to work.
|
||||||
# echo "Generating .NET glue."
|
# echo "Generating .NET glue."
|
||||||
# bin/godot.linuxbsd.editor.x86_64.mono --headless --generate-mono-glue modules/mono/glue
|
# bin/godot.linuxbsd.editor.x86_64.mono --headless --generate-mono-glue modules/mono/glue
|
||||||
# echo "Building .NET assemblies."
|
# echo "Building .NET assemblies."
|
||||||
# # https://docs.godotengine.org/en/stable/contributing/development/compiling/compiling_with_dotnet.html#nuget-packages
|
# # https://docs.godotengine.org/en/stable/contributing/development/compiling/compiling_with_dotnet.html#nuget-packages
|
||||||
# mkdir -p "$HOME/MyLocalNugetSource"
|
# mkdir -p "$HOME/MyLocalNugetSource"
|
||||||
# # Source may already exist, so allow failure for the command below.
|
# # Source may already exist, so allow failure for the command below.
|
||||||
# dotnet nuget add source "$HOME/MyLocalNugetSource" --name MyLocalNugetSource || true
|
# dotnet nuget add source "$HOME/MyLocalNugetSource" --name MyLocalNugetSource || true
|
||||||
# modules/mono/build_scripts/build_assemblies.py --godot-output-dir=./bin --push-nupkgs-local "$HOME/MyLocalNugetSource"
|
# modules/mono/build_scripts/build_assemblies.py --godot-output-dir=./bin --push-nupkgs-local "$HOME/MyLocalNugetSource"
|
||||||
|
|
||||||
cd "$DIR"
|
cd "$DIR"
|
||||||
else
|
else
|
||||||
echo "run-benchmarks: Skipping engine build as requested on the command line."
|
echo "run-benchmarks: Skipping engine build as requested on the command line."
|
||||||
TIME_TO_BUILD_DEBUG=1
|
TIME_TO_BUILD_DEBUG=1
|
||||||
TIME_TO_BUILD_RELEASE=1
|
TIME_TO_BUILD_RELEASE=1
|
||||||
PEAK_MEMORY_BUILD_DEBUG=1
|
PEAK_MEMORY_BUILD_DEBUG=1
|
||||||
PEAK_MEMORY_BUILD_RELEASE=1
|
PEAK_MEMORY_BUILD_RELEASE=1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Path to the Godot debug binary to run. Used for CPU debug benchmarks.
|
# Path to the Godot debug binary to run. Used for CPU debug benchmarks.
|
||||||
@@ -128,7 +128,7 @@ $GODOT_DEBUG --audio-driver Dummy --gpu-index 1 --path "$GODOT_EMPTY_PROJECT_DIR
|
|||||||
TOTAL=0
|
TOTAL=0
|
||||||
for _ in {0..19}; do
|
for _ in {0..19}; do
|
||||||
BEGIN="$(date +%s%3N)"
|
BEGIN="$(date +%s%3N)"
|
||||||
echo "Performing benchmark debug startup/shutdown run."
|
echo "Performing benchmark debug startup/shutdown run."
|
||||||
$GODOT_DEBUG --audio-driver Dummy --gpu-index 1 --path "$GODOT_EMPTY_PROJECT_DIR" --quit || true
|
$GODOT_DEBUG --audio-driver Dummy --gpu-index 1 --path "$GODOT_EMPTY_PROJECT_DIR" --quit || true
|
||||||
END="$(date +%s%3N)"
|
END="$(date +%s%3N)"
|
||||||
TOTAL="$((TOTAL + END - BEGIN))"
|
TOTAL="$((TOTAL + END - BEGIN))"
|
||||||
@@ -144,7 +144,7 @@ $GODOT_RELEASE --audio-driver Dummy --path "$GODOT_EMPTY_PROJECT_DIR" --quit ||
|
|||||||
TOTAL=0
|
TOTAL=0
|
||||||
for _ in {0..19}; do
|
for _ in {0..19}; do
|
||||||
BEGIN="$(date +%s%3N)"
|
BEGIN="$(date +%s%3N)"
|
||||||
echo "Performing benchmark release startup/shutdown run."
|
echo "Performing benchmark release startup/shutdown run."
|
||||||
$GODOT_RELEASE --audio-driver Dummy --path "$GODOT_EMPTY_PROJECT_DIR" --quit || true
|
$GODOT_RELEASE --audio-driver Dummy --path "$GODOT_EMPTY_PROJECT_DIR" --quit || true
|
||||||
END="$(date +%s%3N)"
|
END="$(date +%s%3N)"
|
||||||
TOTAL="$((TOTAL + END - BEGIN))"
|
TOTAL="$((TOTAL + END - BEGIN))"
|
||||||
@@ -199,24 +199,24 @@ BINARY_SIZE_RELEASE="$(stat --printf="%s" "$GODOT_RELEASE")"
|
|||||||
echo "Appending extra JSON at the end of the merged JSON."
|
echo "Appending extra JSON at the end of the merged JSON."
|
||||||
EXTRA_JSON=$(cat << EOF
|
EXTRA_JSON=$(cat << EOF
|
||||||
"binary_size": {
|
"binary_size": {
|
||||||
"debug": $BINARY_SIZE_DEBUG,
|
"debug": $BINARY_SIZE_DEBUG,
|
||||||
"release": $BINARY_SIZE_RELEASE
|
"release": $BINARY_SIZE_RELEASE
|
||||||
},
|
},
|
||||||
"build_time": {
|
"build_time": {
|
||||||
"debug": $TIME_TO_BUILD_DEBUG,
|
"debug": $TIME_TO_BUILD_DEBUG,
|
||||||
"release": $TIME_TO_BUILD_RELEASE
|
"release": $TIME_TO_BUILD_RELEASE
|
||||||
},
|
},
|
||||||
"build_peak_memory_usage": {
|
"build_peak_memory_usage": {
|
||||||
"debug": $PEAK_MEMORY_BUILD_DEBUG,
|
"debug": $PEAK_MEMORY_BUILD_DEBUG,
|
||||||
"release": $PEAK_MEMORY_BUILD_RELEASE
|
"release": $PEAK_MEMORY_BUILD_RELEASE
|
||||||
},
|
},
|
||||||
"empty_project_startup_shutdown_time": {
|
"empty_project_startup_shutdown_time": {
|
||||||
"debug": $TIME_TO_STARTUP_SHUTDOWN_DEBUG,
|
"debug": $TIME_TO_STARTUP_SHUTDOWN_DEBUG,
|
||||||
"release": $TIME_TO_STARTUP_SHUTDOWN_RELEASE
|
"release": $TIME_TO_STARTUP_SHUTDOWN_RELEASE
|
||||||
},
|
},
|
||||||
"empty_project_startup_shutdown_peak_memory_usage": {
|
"empty_project_startup_shutdown_peak_memory_usage": {
|
||||||
"debug": $PEAK_MEMORY_STARTUP_SHUTDOWN_DEBUG,
|
"debug": $PEAK_MEMORY_STARTUP_SHUTDOWN_DEBUG,
|
||||||
"release": $PEAK_MEMORY_STARTUP_SHUTDOWN_RELEASE
|
"release": $PEAK_MEMORY_STARTUP_SHUTDOWN_RELEASE
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,27 +1,27 @@
|
|||||||
Section "ServerLayout"
|
Section "ServerLayout"
|
||||||
Identifier "default-layout"
|
Identifier "default-layout"
|
||||||
Screen 0 "screen"
|
Screen 0 "screen"
|
||||||
EndSection
|
EndSection
|
||||||
|
|
||||||
Section "Device"
|
Section "Device"
|
||||||
Identifier "amd"
|
Identifier "amd"
|
||||||
Driver "amdgpu"
|
Driver "amdgpu"
|
||||||
BusID "PCI:1:0:0"
|
BusID "PCI:1:0:0"
|
||||||
EndSection
|
EndSection
|
||||||
|
|
||||||
Section "Monitor"
|
Section "Monitor"
|
||||||
Identifier "monitor"
|
Identifier "monitor"
|
||||||
Modeline "1920x1200_60.00" 193.25 1920 2056 2256 2592 1200 1203 1209 1245 -hsync +vsync
|
Modeline "1920x1200_60.00" 193.25 1920 2056 2256 2592 1200 1203 1209 1245 -hsync +vsync
|
||||||
Option "PreferredMode" "1920x1080_60.00"
|
Option "PreferredMode" "1920x1080_60.00"
|
||||||
EndSection
|
EndSection
|
||||||
|
|
||||||
Section "Screen"
|
Section "Screen"
|
||||||
Identifier "screen"
|
Identifier "screen"
|
||||||
Device "amd"
|
Device "amd"
|
||||||
Monitor "monitor"
|
Monitor "monitor"
|
||||||
DefaultDepth 24
|
DefaultDepth 24
|
||||||
SubSection "Display"
|
SubSection "Display"
|
||||||
Depth 24
|
Depth 24
|
||||||
Modes "1920x1080"
|
Modes "1920x1080"
|
||||||
EndSubSection
|
EndSubSection
|
||||||
EndSection
|
EndSection
|
||||||
|
|||||||
1
web/.gitattributes
vendored
1
web/.gitattributes
vendored
@@ -1 +0,0 @@
|
|||||||
static/thirdparty/* linguist-vendored
|
|
||||||
14
web/.gitignore
vendored
14
web/.gitignore
vendored
@@ -1,14 +0,0 @@
|
|||||||
# Output HTML files
|
|
||||||
public/
|
|
||||||
|
|
||||||
# Temporary lock file while building
|
|
||||||
.hugo_build.lock
|
|
||||||
|
|
||||||
# Generated files
|
|
||||||
content/benchmark/*.md
|
|
||||||
content/graph/*.md
|
|
||||||
data/data.json
|
|
||||||
|
|
||||||
# Untracked source files
|
|
||||||
src-data/benchmarks/*.md
|
|
||||||
src-data/benchmarks/*.json
|
|
||||||
@@ -1,209 +1,209 @@
|
|||||||
function getAllowedMetrics() {
|
function getAllowedMetrics() {
|
||||||
const allowedMetrics = new Set();
|
const allowedMetrics = new Set();
|
||||||
Database.benchmarks.forEach((benchmark) => {
|
Database.benchmarks.forEach((benchmark) => {
|
||||||
benchmark.benchmarks.forEach((instance) => {
|
benchmark.benchmarks.forEach((instance) => {
|
||||||
Object.entries(instance.results).forEach(([key, value]) => {
|
Object.entries(instance.results).forEach(([key, value]) => {
|
||||||
allowedMetrics.add(key);
|
allowedMetrics.add(key);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
return allowedMetrics;
|
return allowedMetrics;
|
||||||
}
|
}
|
||||||
|
|
||||||
function displayGraph(targetDivID, graphID, type = "full", filter = "") {
|
function displayGraph(targetDivID, graphID, type = "full", filter = "") {
|
||||||
if (!["full", "compact"].includes(type)) {
|
if (!["full", "compact"].includes(type)) {
|
||||||
throw Error("Unknown chart type");
|
throw Error("Unknown chart type");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Include benchmark data JSON to generate graphs.
|
// Include benchmark data JSON to generate graphs.
|
||||||
const allBenchmarks = Database.benchmarks.sort(
|
const allBenchmarks = Database.benchmarks.sort(
|
||||||
(a, b) => `${a.date}.${a.commit}` > `${b.date}.${b.commit}`,
|
(a, b) => `${a.date}.${a.commit}` > `${b.date}.${b.commit}`,
|
||||||
);
|
);
|
||||||
const graph = Database.graphs.find((g) => g.id == graphID);
|
const graph = Database.graphs.find((g) => g.id == graphID);
|
||||||
if (!graph) {
|
if (!graph) {
|
||||||
throw new Error("Invalid graph ID");
|
throw new Error("Invalid graph ID");
|
||||||
}
|
}
|
||||||
// Group by series.
|
// Group by series.
|
||||||
const xAxis = [];
|
const xAxis = [];
|
||||||
const series = new Map();
|
const series = new Map();
|
||||||
const processResult = (path, data, process) => {
|
const processResult = (path, data, process) => {
|
||||||
Object.entries(data).forEach(([key, value]) => {
|
Object.entries(data).forEach(([key, value]) => {
|
||||||
if (typeof value === "object") {
|
if (typeof value === "object") {
|
||||||
processResult(path + "/" + key, value, process);
|
processResult(path + "/" + key, value, process);
|
||||||
} else {
|
} else {
|
||||||
// Number
|
// Number
|
||||||
process(path + "/" + key, value);
|
process(path + "/" + key, value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get list all series and fill it in.
|
// Get list all series and fill it in.
|
||||||
allBenchmarks.forEach((benchmark, count) => {
|
allBenchmarks.forEach((benchmark, count) => {
|
||||||
// Process a day/commit
|
// Process a day/commit
|
||||||
xAxis.push(benchmark.date + "." + benchmark.commit);
|
xAxis.push(benchmark.date + "." + benchmark.commit);
|
||||||
|
|
||||||
// Get all series.
|
// Get all series.
|
||||||
benchmark.benchmarks.forEach((instance) => {
|
benchmark.benchmarks.forEach((instance) => {
|
||||||
let instanceKey = instance.path.join("/");
|
let instanceKey = instance.path.join("/");
|
||||||
if (!instanceKey.startsWith(graph["benchmark-path-prefix"])) {
|
if (!instanceKey.startsWith(graph["benchmark-path-prefix"])) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
instanceKey = instanceKey.slice(
|
instanceKey = instanceKey.slice(
|
||||||
graph["benchmark-path-prefix"].length + 1,
|
graph["benchmark-path-prefix"].length + 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
processResult(instanceKey, instance.results, (path, value) => {
|
processResult(instanceKey, instance.results, (path, value) => {
|
||||||
// Filter out paths that do not fit the filter
|
// Filter out paths that do not fit the filter
|
||||||
if (filter && !path.includes(filter)) {
|
if (filter && !path.includes(filter)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!series.has(path)) {
|
if (!series.has(path)) {
|
||||||
series.set(path, Array(count).fill(null));
|
series.set(path, Array(count).fill(null));
|
||||||
}
|
}
|
||||||
series.get(path).push(value);
|
series.get(path).push(value);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
let customColor = undefined;
|
let customColor = undefined;
|
||||||
|
|
||||||
if (type === "compact") {
|
if (type === "compact") {
|
||||||
// Kind of "normalize" the series, dividing by the average.
|
// Kind of "normalize" the series, dividing by the average.
|
||||||
series.forEach((serie, key) => {
|
series.forEach((serie, key) => {
|
||||||
let count = 0;
|
let count = 0;
|
||||||
let mean = 0.0;
|
let mean = 0.0;
|
||||||
serie.forEach((el) => {
|
serie.forEach((el) => {
|
||||||
if (el != null) {
|
if (el != null) {
|
||||||
mean += el;
|
mean += el;
|
||||||
count += 1;
|
count += 1;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
mean = mean / count;
|
mean = mean / count;
|
||||||
|
|
||||||
//const std = Math.sqrt(input.map(x => Math.pow(x - mean, 2)).reduce((a, b) => a + b) / n)
|
//const std = Math.sqrt(input.map(x => Math.pow(x - mean, 2)).reduce((a, b) => a + b) / n)
|
||||||
series.set(
|
series.set(
|
||||||
key,
|
key,
|
||||||
serie.map((v) => {
|
serie.map((v) => {
|
||||||
if (v != null) {
|
if (v != null) {
|
||||||
return v / mean; // Devide by the mean.
|
return v / mean; // Devide by the mean.
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
// Combine all into a single, averaged serie.
|
// Combine all into a single, averaged serie.
|
||||||
const outputSerie = [];
|
const outputSerie = [];
|
||||||
for (let i = 0; i < allBenchmarks.length; i++) {
|
for (let i = 0; i < allBenchmarks.length; i++) {
|
||||||
let count = 0;
|
let count = 0;
|
||||||
let sum = 0;
|
let sum = 0;
|
||||||
series.forEach((serie, key) => {
|
series.forEach((serie, key) => {
|
||||||
if (serie[i] != null) {
|
if (serie[i] != null) {
|
||||||
count += 1;
|
count += 1;
|
||||||
sum += serie[i];
|
sum += serie[i];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let point = null;
|
let point = null;
|
||||||
if (count >= 1) {
|
if (count >= 1) {
|
||||||
point = Math.round((sum * 1000) / count) / 10; // Round to 3 decimals.
|
point = Math.round((sum * 1000) / count) / 10; // Round to 3 decimals.
|
||||||
}
|
}
|
||||||
outputSerie.push(point);
|
outputSerie.push(point);
|
||||||
}
|
}
|
||||||
series.clear();
|
series.clear();
|
||||||
series.set("Average", outputSerie);
|
series.set("Average", outputSerie);
|
||||||
|
|
||||||
// Detect whether we went down or not on the last 10 benchmarks.
|
// Detect whether we went down or not on the last 10 benchmarks.
|
||||||
const lastElementsCount = 3;
|
const lastElementsCount = 3;
|
||||||
const totalConsideredCount = 10;
|
const totalConsideredCount = 10;
|
||||||
const lastElements = outputSerie.slice(-lastElementsCount);
|
const lastElements = outputSerie.slice(-lastElementsCount);
|
||||||
const comparedTo = outputSerie.slice(
|
const comparedTo = outputSerie.slice(
|
||||||
-totalConsideredCount,
|
-totalConsideredCount,
|
||||||
-lastElementsCount,
|
-lastElementsCount,
|
||||||
);
|
);
|
||||||
const avgLast = lastElements.reduce((a, b) => a + b) / lastElements.length;
|
const avgLast = lastElements.reduce((a, b) => a + b) / lastElements.length;
|
||||||
const avgComparedTo =
|
const avgComparedTo =
|
||||||
comparedTo.reduce((a, b) => a + b) / comparedTo.length;
|
comparedTo.reduce((a, b) => a + b) / comparedTo.length;
|
||||||
const trend = avgLast - avgComparedTo;
|
const trend = avgLast - avgComparedTo;
|
||||||
|
|
||||||
if (trend > 10) {
|
if (trend > 10) {
|
||||||
customColor = "#E20000";
|
customColor = "#E20000";
|
||||||
} else if (trend < -10) {
|
} else if (trend < -10) {
|
||||||
customColor = "#00E200";
|
customColor = "#00E200";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var options = {
|
var options = {
|
||||||
series: Array.from(series.entries()).map(([key, value]) => ({
|
series: Array.from(series.entries()).map(([key, value]) => ({
|
||||||
name: key,
|
name: key,
|
||||||
data: value,
|
data: value,
|
||||||
})),
|
})),
|
||||||
chart: {
|
chart: {
|
||||||
foreColor: "var(--text-bright)",
|
foreColor: "var(--text-bright)",
|
||||||
background: "var(--background)",
|
background: "var(--background)",
|
||||||
height: type === "compact" ? 200 : 600,
|
height: type === "compact" ? 200 : 600,
|
||||||
type: "line",
|
type: "line",
|
||||||
zoom: {
|
zoom: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
},
|
},
|
||||||
toolbar: {
|
toolbar: {
|
||||||
show: false,
|
show: false,
|
||||||
},
|
},
|
||||||
animations: {
|
animations: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
theme: "dark",
|
theme: "dark",
|
||||||
y: {
|
y: {
|
||||||
formatter: (value, opts) => (type === "compact" ? value + "%" : value),
|
formatter: (value, opts) => (type === "compact" ? value + "%" : value),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
dataLabels: {
|
dataLabels: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
},
|
},
|
||||||
stroke: {
|
stroke: {
|
||||||
curve: "straight",
|
curve: "straight",
|
||||||
width: 2,
|
width: 2,
|
||||||
},
|
},
|
||||||
theme: {
|
theme: {
|
||||||
palette: "palette4",
|
palette: "palette4",
|
||||||
},
|
},
|
||||||
fill:
|
fill:
|
||||||
type === "compact"
|
type === "compact"
|
||||||
? {
|
? {
|
||||||
type: "gradient",
|
type: "gradient",
|
||||||
gradient: {
|
gradient: {
|
||||||
shade: "dark",
|
shade: "dark",
|
||||||
gradientToColors: ["#4ecdc4"],
|
gradientToColors: ["#4ecdc4"],
|
||||||
shadeIntensity: 1,
|
shadeIntensity: 1,
|
||||||
type: "horizontal",
|
type: "horizontal",
|
||||||
opacityFrom: 1,
|
opacityFrom: 1,
|
||||||
opacityTo: 1,
|
opacityTo: 1,
|
||||||
stops: [0, 100],
|
stops: [0, 100],
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
: {},
|
: {},
|
||||||
colors:
|
colors:
|
||||||
type === "compact"
|
type === "compact"
|
||||||
? customColor
|
? customColor
|
||||||
? [customColor]
|
? [customColor]
|
||||||
: ["#4ecdc4"]
|
: ["#4ecdc4"]
|
||||||
: undefined,
|
: undefined,
|
||||||
xaxis: {
|
xaxis: {
|
||||||
categories: xAxis,
|
categories: xAxis,
|
||||||
labels: {
|
labels: {
|
||||||
show: type !== "compact",
|
show: type !== "compact",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
yaxis: {
|
yaxis: {
|
||||||
tickAmount: 4,
|
tickAmount: 4,
|
||||||
min: type === "compact" ? 0 : undefined,
|
min: type === "compact" ? 0 : undefined,
|
||||||
max: type === "compact" ? 200 : undefined,
|
max: type === "compact" ? 200 : undefined,
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
show: type !== "compact",
|
show: type !== "compact",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
var chart = new ApexCharts(document.querySelector(targetDivID), options);
|
var chart = new ApexCharts(document.querySelector(targetDivID), options);
|
||||||
chart.render();
|
chart.render();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,39 +1,39 @@
|
|||||||
/* See `thirdparty/water.css` for CSS variables that can be used here. */
|
/* See `thirdparty/water.css` for CSS variables that can be used here. */
|
||||||
|
|
||||||
p, li {
|
p, li {
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
footer {
|
footer {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
header {
|
header {
|
||||||
background-color: var(--background);
|
background-color: var(--background);
|
||||||
border-radius: 0 0 6px 6px;
|
border-radius: 0 0 6px 6px;
|
||||||
padding: .75rem 2rem;
|
padding: .75rem 2rem;
|
||||||
margin-top: -1.25rem;
|
margin-top: -1.25rem;
|
||||||
margin-bottom: 2rem;
|
margin-bottom: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.site-title {
|
.site-title {
|
||||||
color: var(--text-bright);
|
color: var(--text-bright);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: 1.25rem;
|
font-size: 1.25rem;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Automatically resize the left column to take as little space as required. */
|
/* Automatically resize the left column to take as little space as required. */
|
||||||
.table-first-column-align-right {
|
.table-first-column-align-right {
|
||||||
width: auto;
|
width: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Align first column to the right to improve readability in some situations. */
|
/* Align first column to the right to improve readability in some situations. */
|
||||||
.table-first-column-align-right tr td:first-of-type {
|
.table-first-column-align-right tr td:first-of-type {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
width: 1%;
|
width: 1%;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
/* Style the first column as headings. */
|
/* Style the first column as headings. */
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user