Compare commits

..

5 Commits
v4.4 ... master

Author SHA1 Message Date
Andrei Pangin
b2a98f5f8c Use .yml extension for workflows 2026-04-28 17:29:41 +01:00
Ben Taylor
b360918cd8 Normalize Makefile on 7 char short hashes (#1732) 2026-04-28 17:26:33 +01:00
Ben Taylor
5853965e4c Add workflow to post binary size comparison to pull request comments (#1722) 2026-04-28 01:41:18 +01:00
Andrei Pangin
d3e30d9d6a Updated links to v4.4 2026-04-20 23:31:26 +01:00
Andrei Pangin
f6ca3c1ff8 dumpOtlp() should accept Counter argument (#1728) 2026-04-15 19:38:08 +01:00
10 changed files with 76 additions and 14 deletions

View File

@@ -0,0 +1,28 @@
name: compare-binary-sizes
on:
workflow_run:
workflows: [CI]
types: [completed]
permissions:
contents: read
pull-requests: write
actions: read
env:
GH_TOKEN: "${{ github.token }}"
REPO: "${{ github.repository }}"
PR_SHA: "${{ github.event.workflow_run.head_sha }}"
jobs:
compare:
if: ${{ github.event.workflow_run.event == 'pull_request' }}
runs-on: ubuntu-latest
steps:
- run: |
gh api "repos/${REPO}/contents/scripts/compare-binary-sizes.sh" -H 'Accept: application/vnd.github.raw' > compare.sh
read pr base_sha < <(gh api "repos/${REPO}/commits/${PR_SHA}/pulls" --jq '.[0] | "\(.number) \(.base.sha)"')
function find-archive() { find "${1}" -type f \( -name "async-profiler-*${2}.tar.gz" -o -name "async-profiler-*${2}.zip" \) ! -name '*-debug*' | head -n1; }
for p in linux-x64 linux-arm64 macos; do
gh run download -R "${REPO}" -n "async-profiler-${p}-${base_sha:0:7}" -D "base/${p}" 2>/dev/null || continue
gh run download -R "${REPO}" -n "async-profiler-${p}-${PR_SHA:0:7}" -D "pr/${p}" 2>/dev/null || continue
bash compare.sh "$(find-archive "base/${p}" "${p}")" "$(find-archive "pr/${p}" "${p}")" >> report.md
done
gh pr comment "${pr}" -R "${REPO}" --body-file report.md --edit-last --create-if-none

2
.gitignore vendored
View File

@@ -8,3 +8,5 @@
*.iml
/src/api/**/*.class
.gdb_history
async-profiler-*.tar.gz
async-profiler-*.zip

View File

@@ -1,6 +1,6 @@
# Changelog
## [4.4]
## [4.4] - 2026-04-20
### Features

View File

@@ -1,7 +1,7 @@
PROFILER_VERSION ?= 4.4
ifeq ($(COMMIT_TAG),true)
PROFILER_VERSION := $(PROFILER_VERSION)-$(shell git rev-parse --short=8 HEAD)
PROFILER_VERSION := $(PROFILER_VERSION)-$(shell git rev-parse --short=7 HEAD)
else ifneq ($(COMMIT_TAG),)
PROFILER_VERSION := $(PROFILER_VERSION)-$(COMMIT_TAG)
endif

View File

@@ -23,12 +23,12 @@ to learn about more features.
# Download
### Stable release: [4.3](https://github.com/async-profiler/async-profiler/releases/tag/v4.3)
### Stable release: [4.4](https://github.com/async-profiler/async-profiler/releases/tag/v4.4)
- Linux x64: [async-profiler-4.3-linux-x64.tar.gz](https://github.com/async-profiler/async-profiler/releases/download/v4.3/async-profiler-4.3-linux-x64.tar.gz)
- Linux arm64: [async-profiler-4.3-linux-arm64.tar.gz](https://github.com/async-profiler/async-profiler/releases/download/v4.3/async-profiler-4.3-linux-arm64.tar.gz)
- macOS arm64/x64: [async-profiler-4.3-macos.zip](https://github.com/async-profiler/async-profiler/releases/download/v4.3/async-profiler-4.3-macos.zip)
- Profile converters: [jfr-converter.jar](https://github.com/async-profiler/async-profiler/releases/download/v4.3/jfr-converter.jar)
- Linux x64: [async-profiler-4.4-linux-x64.tar.gz](https://github.com/async-profiler/async-profiler/releases/download/v4.4/async-profiler-4.4-linux-x64.tar.gz)
- Linux arm64: [async-profiler-4.4-linux-arm64.tar.gz](https://github.com/async-profiler/async-profiler/releases/download/v4.4/async-profiler-4.4-linux-arm64.tar.gz)
- macOS arm64/x64: [async-profiler-4.4-macos.zip](https://github.com/async-profiler/async-profiler/releases/download/v4.4/async-profiler-4.4-macos.zip)
- Profile converters: [jfr-converter.jar](https://github.com/async-profiler/async-profiler/releases/download/v4.4/jfr-converter.jar)
### Nightly builds

31
scripts/compare-binary-sizes.sh Executable file
View File

@@ -0,0 +1,31 @@
#!/usr/bin/env bash
# Copyright The async-profiler authors
# SPDX-License-Identifier: Apache-2.0
set -euo pipefail
function list-archive() {
case "${1}" in
*.tar.gz) tar -tzvf "${1}" --wildcards '*/bin/*' '*/lib/*' | awk '$1 ~ /^-/ { print $NF, $3 }' ;;
*.zip) zipinfo -l "${1}" '*/bin/*' '*/lib/*' | awk '$1 ~ /^-/ { print $NF, $4 }' ;;
esac | cut -d/ -f2- | sort
}
function main() {
if [[ ${#} -ne 2 ]]; then
printf 'Usage: compare-binary-sizes.sh <base-archive> <treatment-archive>\n' >&2
exit 1
fi
[[ ${1} =~ (linux-x64|linux-arm64|macos) ]]
printf '### %s\n\n| File | Base (KiB) | Treatment (KiB) | Delta (KiB) | %% Change |\n| --- | ---: | ---: | ---: | ---: |\n' "${BASH_REMATCH[1]}"
join -a1 -a2 -e0 -o '0,1.2,2.2' \
<(list-archive "${1}") \
<(list-archive "${2}") \
| awk '{
b = $2; t = $3; d = t - b; pct = b > 0 ? d * 100 / b : 0
printf "| `%s` | %.2f | %.2f | %+.2f | %+.2f%% |\n", $1, b/1024, t/1024, d/1024, pct
}'
}
[[ "${BASH_SOURCE[0]}" == "${0}" ]] && main "$@"

View File

@@ -201,7 +201,7 @@ public class AsyncProfiler implements AsyncProfilerMXBean {
@Override
public String dumpCollapsed(Counter counter) {
try {
return execute0("collapsed," + counter.name().toLowerCase());
return execute0("collapsed," + (counter == Counter.SAMPLES ? "samples" : "total"));
} catch (IOException e) {
throw new IllegalStateException(e);
}
@@ -242,12 +242,13 @@ public class AsyncProfiler implements AsyncProfilerMXBean {
* <p>
* This API is UNSTABLE and might change or be removed in the next version of async-profiler.
*
* @param counter Which counter to use for aggregation
* @return OTLP representation of the profile
*/
@Override
public byte[] dumpOtlp() {
public byte[] dumpOtlp(Counter counter) {
try {
return execute1("otlp");
return execute1("otlp," + (counter == Counter.SAMPLES ? "samples" : "total"));
} catch (IOException e) {
throw new IllegalStateException(e);
}

View File

@@ -31,5 +31,5 @@ public interface AsyncProfilerMXBean {
String dumpCollapsed(Counter counter);
String dumpTraces(int maxTraces);
String dumpFlat(int maxMethods);
byte[] dumpOtlp();
byte[] dumpOtlp(Counter counter);
}

View File

@@ -5,7 +5,6 @@
package test.api;
import java.nio.ByteBuffer;
import one.profiler.AsyncProfiler;
import one.profiler.Counter;
import one.profiler.Events;
@@ -22,7 +21,7 @@ public class DumpOtlp extends BusyLoops {
}
// TODO: Should we test this further?
byte[] profile = AsyncProfiler.getInstance().dumpOtlp();
byte[] profile = AsyncProfiler.getInstance().dumpOtlp(Counter.TOTAL);
System.out.println(profile.length);
}
}

View File

@@ -5,6 +5,7 @@
package test.otlp;
import one.profiler.AsyncProfiler;
import one.profiler.Counter;
import one.profiler.Events;
import io.opentelemetry.proto.profiles.v1development.*;
@@ -39,7 +40,7 @@ public class OtlpProfileTimeTest {
}
public static Profile dumpAndGetProfile(AsyncProfiler profiler) throws Exception {
byte[] dump = profiler.dumpOtlp();
byte[] dump = profiler.dumpOtlp(Counter.SAMPLES);
ProfilesData data = ProfilesData.parseFrom(dump);
return data.getResourceProfiles(0).getScopeProfiles(0).getProfiles(0);
}