-
Notifications
You must be signed in to change notification settings - Fork 60
216 lines (185 loc) · 9.23 KB
/
native-ast-perf.yml
File metadata and controls
216 lines (185 loc) · 9.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
name: Native AST Walk Perf
on:
push:
paths:
- '.github/workflows/native-ast-perf.yml'
- 'packages/mysql-on-sqlite/src/mysql/native/**'
- 'packages/mysql-on-sqlite/tests/tools/run-native-ast-walk-benchmark.php'
- 'packages/php-ext-wp-mysql-parser/**'
pull_request:
paths:
- '.github/workflows/native-ast-perf.yml'
- 'packages/mysql-on-sqlite/src/mysql/native/**'
- 'packages/mysql-on-sqlite/tests/tools/run-native-ast-walk-benchmark.php'
- 'packages/php-ext-wp-mysql-parser/**'
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
perf:
name: Native AST walk benchmark
runs-on: ubuntu-latest
timeout-minutes: 25
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
coverage: none
- name: Set up Rust
uses: dtolnay/rust-toolchain@stable
- name: Install native build dependencies
run: |
sudo apt-get update
sudo apt-get install -y libclang-dev
echo "PHP_CONFIG=$(command -v php-config)" >> "$GITHUB_ENV"
LIBCLANG_SO="$(find /usr/lib -name 'libclang.so*' | head -n 1)"
echo "LIBCLANG_PATH=$(dirname "$LIBCLANG_SO")" >> "$GITHUB_ENV"
- name: Install Composer dependencies (root)
uses: ramsey/composer-install@v3
with:
ignore-cache: "yes"
composer-options: "--optimize-autoloader"
- name: Install Composer dependencies (mysql-on-sqlite)
uses: ramsey/composer-install@v3
with:
working-directory: packages/mysql-on-sqlite
ignore-cache: "yes"
composer-options: "--optimize-autoloader"
- name: Download MySQL test query corpus
working-directory: packages/mysql-on-sqlite
run: bash tests/tools/mysql-download-tests.sh || true
- name: Build parser extension (release)
run: cargo build --release
working-directory: packages/php-ext-wp-mysql-parser
- name: Locate built extension
run: |
EXT="$GITHUB_WORKSPACE/packages/php-ext-wp-mysql-parser/target/release/libwp_mysql_parser.so"
test -f "$EXT" || { echo "Extension not built at $EXT"; exit 1; }
echo "NATIVE_EXT=$EXT" >> "$GITHUB_ENV"
- name: Benchmark — pure-PHP path (parse only)
working-directory: packages/mysql-on-sqlite
run: |
php tests/tools/run-native-ast-walk-benchmark.php --no-walk | tee php-parse-only.txt
- name: Benchmark — pure-PHP path (walk)
working-directory: packages/mysql-on-sqlite
run: |
php tests/tools/run-native-ast-walk-benchmark.php | tee php-walk.txt
- name: Benchmark — native path (parse only)
working-directory: packages/mysql-on-sqlite
run: |
php -d extension="$NATIVE_EXT" tests/tools/run-native-ast-walk-benchmark.php --no-walk | tee native-parse-only.txt
- name: Benchmark — native path (walk, with identity cache)
working-directory: packages/mysql-on-sqlite
run: |
php -d extension="$NATIVE_EXT" tests/tools/run-native-ast-walk-benchmark.php | tee native-walk.txt
- name: Check out baseline (PR base, no identity cache)
run: |
git fetch --no-tags --depth=1 origin codex/native-lazy-ast-facade
git worktree add ../baseline FETCH_HEAD
- name: Install Composer dependencies (baseline mysql-on-sqlite)
uses: ramsey/composer-install@v3
with:
working-directory: ../baseline/packages/mysql-on-sqlite
ignore-cache: "yes"
composer-options: "--optimize-autoloader"
- name: Build baseline parser extension (release)
run: cargo build --release
working-directory: ../baseline/packages/php-ext-wp-mysql-parser
- name: Stage benchmark + corpus into baseline
run: |
mkdir -p ../baseline/packages/mysql-on-sqlite/tests/mysql/data
cp packages/mysql-on-sqlite/tests/tools/run-native-ast-walk-benchmark.php \
../baseline/packages/mysql-on-sqlite/tests/tools/
cp packages/mysql-on-sqlite/tests/mysql/data/*.csv \
../baseline/packages/mysql-on-sqlite/tests/mysql/data/ 2>/dev/null || true
- name: Benchmark — baseline native path (walk, no identity cache)
working-directory: ../baseline/packages/mysql-on-sqlite
run: |
BASE_EXT="$(realpath ../../packages/php-ext-wp-mysql-parser/target/release/libwp_mysql_parser.so)"
php -d extension="$BASE_EXT" tests/tools/run-native-ast-walk-benchmark.php \
| tee "$GITHUB_WORKSPACE/packages/mysql-on-sqlite/baseline-native-walk.txt"
- name: Benchmark — baseline native path (parse only)
working-directory: ../baseline/packages/mysql-on-sqlite
run: |
BASE_EXT="$(realpath ../../packages/php-ext-wp-mysql-parser/target/release/libwp_mysql_parser.so)"
php -d extension="$BASE_EXT" tests/tools/run-native-ast-walk-benchmark.php --no-walk \
| tee "$GITHUB_WORKSPACE/packages/mysql-on-sqlite/baseline-native-parse-only.txt"
# Hit-heavy scenarios — these are where the per-AST identity cache is
# supposed to win. The baseline reallocates wrappers on every accessor
# call, while the PR reuses them. Run on both to make the gap visible.
- name: Benchmark — native rewalk x10 (this PR)
working-directory: packages/mysql-on-sqlite
run: |
php -d extension="$NATIVE_EXT" tests/tools/run-native-ast-walk-benchmark.php --mode=rewalk --repeat=10 \
| tee native-rewalk.txt
- name: Benchmark — baseline rewalk x10
working-directory: ../baseline/packages/mysql-on-sqlite
run: |
BASE_EXT="$(realpath ../../packages/php-ext-wp-mysql-parser/target/release/libwp_mysql_parser.so)"
php -d extension="$BASE_EXT" tests/tools/run-native-ast-walk-benchmark.php --mode=rewalk --repeat=10 \
| tee "$GITHUB_WORKSPACE/packages/mysql-on-sqlite/baseline-native-rewalk.txt"
- name: Benchmark — native reread x20 (this PR)
working-directory: packages/mysql-on-sqlite
run: |
php -d extension="$NATIVE_EXT" tests/tools/run-native-ast-walk-benchmark.php --mode=reread --repeat=20 \
| tee native-reread.txt
- name: Benchmark — baseline reread x20
working-directory: ../baseline/packages/mysql-on-sqlite
run: |
BASE_EXT="$(realpath ../../packages/php-ext-wp-mysql-parser/target/release/libwp_mysql_parser.so)"
php -d extension="$BASE_EXT" tests/tools/run-native-ast-walk-benchmark.php --mode=reread --repeat=20 \
| tee "$GITHUB_WORKSPACE/packages/mysql-on-sqlite/baseline-native-reread.txt"
- name: Benchmark — native subtree x5 (this PR)
working-directory: packages/mysql-on-sqlite
run: |
php -d extension="$NATIVE_EXT" tests/tools/run-native-ast-walk-benchmark.php --mode=subtree --repeat=5 \
| tee native-subtree.txt
- name: Benchmark — baseline subtree x5
working-directory: ../baseline/packages/mysql-on-sqlite
run: |
BASE_EXT="$(realpath ../../packages/php-ext-wp-mysql-parser/target/release/libwp_mysql_parser.so)"
php -d extension="$BASE_EXT" tests/tools/run-native-ast-walk-benchmark.php --mode=subtree --repeat=5 \
| tee "$GITHUB_WORKSPACE/packages/mysql-on-sqlite/baseline-native-subtree.txt"
- name: Summarize
if: always()
working-directory: packages/mysql-on-sqlite
run: |
extract() {
# Pull a numeric field (e.g. duration=1.23s) from a benchmark
# output line. Returns "n/a" if missing.
local file="$1" key="$2"
[ -f "$file" ] || { echo "n/a"; return; }
grep -oE "${key}=[^ ]+" "$file" | head -1 | cut -d= -f2 || echo "n/a"
}
{
echo '### Native AST walk perf'
echo
echo '| scenario | result |'
echo '|---|---|'
for f in php-parse-only.txt php-walk.txt native-parse-only.txt native-walk.txt baseline-native-parse-only.txt baseline-native-walk.txt native-rewalk.txt baseline-native-rewalk.txt native-reread.txt baseline-native-reread.txt native-subtree.txt baseline-native-subtree.txt; do
[ -f "$f" ] || continue
line="$(cat "$f")"
echo "| ${f%.txt} | \`$line\` |"
done
echo
echo '### Identity-cache cost (native walk: with cache vs PR base without)'
echo
echo '| metric | with cache (this PR) | baseline | delta |'
echo '|---|---|---|---|'
for key in duration qps peak_mem walked_nodes; do
with="$(extract native-walk.txt "$key")"
base="$(extract baseline-native-walk.txt "$key")"
echo "| $key | $with | $base | — |"
done
} >> "$GITHUB_STEP_SUMMARY"
- name: Upload raw output
if: always()
uses: actions/upload-artifact@v4
with:
name: native-ast-perf-${{ github.run_id }}
path: packages/mysql-on-sqlite/*.txt
if-no-files-found: warn