[WIP] Experiment with alternate FastDeploy strategies#11692
[WIP] Experiment with alternate FastDeploy strategies#11692simonrozsival wants to merge 12 commits into
Conversation
Introduce FastDeploy2 and FastDeploy3 as opt-in fast deployment strategies for comparing adb push --sync and adb sync based file transfer paths. Add diagnostic timing counters to the legacy FastDeploy path for preliminary benchmarking. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Capture non-transfer phase timings for FastDeploy2 and FastDeploy3 so the constant overhead can be broken down separately from staging, upload, stat, and copy work. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Additional overhead instrumentation results: Device: Samsung Galaxy A16 (
The previous ~1.7s “Other” bucket is mostly explained by first-install orchestration:
So there is no longer a large unexplained constant inside the task after instrumentation; the large apparent “other” in prior tables was because package install/termination/checks were not separately timed. |
Break orchestration timing down into package checks, package install, process lookup/kill, and execute/setup substeps so the fixed costs can be measured independently from file transfer phases. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Fine-grained orchestration breakdown after adding more timers: Device: Samsung Galaxy A16 ( FastDeploy2
FastDeploy3
Observations:
|
|
Interleaved benchmark across all three strategies, with first-deploy runs cleaning app data and temp staging dirs before each strategy. Cleanup before each first-deploy sequence: adb uninstall com.xamarin.android.helloworld
adb shell rm -rf /tmp/fastdev2/com.xamarin.android.helloworld/0 \
/data/local/tmp/fastdeploy3/com.xamarin.android.helloworld/0 \
/data/local/tmp/.xatools
rm obj/Debug/net11.0-android/uploadflags.txtDevice: Samsung Galaxy A16 (
Aggregate timings
Simple warm-case fit using touch-one + touch-all main-transfer times:
Main transfer means:
Risk notes for switching away from legacy FastDeployFastDeploy2/3 look much better for full transfers, but key risks remain:
|
Introduce FastDeploy4 with direct original-file adb push support and selectable SingleFile/Bulk push modes so local staging costs can be evaluated independently. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
FastDeploy4 experiment: direct original-file adb push without local staging. Strategy shape:
Usage: -p:_AndroidFastDevStrategy=FastDeploy4
-p:_AndroidFastDeploy4PushMode=SingleFile|BulkBenchmark on Samsung Galaxy A16 (
Takeaways:
|
Have experimental FastDeploy strategies retrieve the app private path and process id in a single run-as shell invocation so process termination can avoid a separate adb ps call when possible. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Tried combining the package/private-directory probe and process lookup into a single The command shape is effectively: run-as <pkg> sh -c 'pwd; pidof <pkg> 2>/dev/null || true'This returns the app data dir on line 1 and the process id on line 2 when the app is running. The experimental FastDeploy tasks now cache that pid and avoid the separate Validation on the Samsung device:
So this removes one adb process-list call from the incremental path while preserving the actual kill behavior when the app is running. |
Allow FastDeploy2-derived strategies to replace app-private copies with symlinks to staged files so the app storage transfer cost can be measured separately from upload and staging. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Additional direct-push and symlink experiments. FastDeploy4: direct original-file pushFastDeploy4 avoids local staging and pushes original source files directly to remote staging.
Takeaway: avoiding local staging works, but one adb invocation per file is too expensive. Bulk direct push is viable, but still slower than staged directory push in some cases. Symlink app transfer modeI also tested replacing app-private Manual probe:
Integrated FastDeploy2 experiment with
Notes:
|
|
Per-file adb invocation timing probe for the FastDeploy payload. Payload: 195 files, 144.5 MB total, pushed one file at a time with: adb push -z any --sync local-file remote-fileFirst upload, one adb invocation per file
Slowest files were the genuinely large files ( Unchanged upload, one adb invocation per file
This confirms the hypothesis: even a skipped per-file Implication: one-by-one push is only attractive if we already know a very small changed set. It is not viable as a way to discover changed files by probing all FastDev files. |
Convert the experimental FastDeploy2 strategy to bulk-push original FastDev inputs directly to /tmp/fastdev2 without host-side staging, and use symlinks in files/.__override__ by default. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Updated FastDeploy2 to the current preferred experiment shape: This removes host-side staging for normal files and avoids app-private Usage: -p:_AndroidFastDevStrategy=FastDeploy2
-p:_AndroidFastDeployAppFileTransferMode=CopyLatest Samsung A16 numbers:
The app launched successfully from the symlinked override tree after the run ( Notes:
|
|
Compression algorithm experiment for the current FastDeploy2 shape (direct bulk push to Device: Samsung Galaxy A16 (
Observations:
For now, |
|
More realistic app-development scenario: touch only app-specific DLLs, leave BCL/SDK/framework DLLs unchanged. Touched files:
Total touched DLL bytes: ~15 KB Each strategy was first given a clean baseline deploy, then only those app DLLs were touched before the measured deploy.
Observations:
|
Avoid probing normal FastDev source files before adb push and keep the generated environment blob timestamp-stable by only rewriting it when content changes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Small cleanup to the direct-push preparation path:
Quick verification: So unchanged environment content no longer dirties the environment blob timestamp. |
Add a native maui.link helper for the experimental symlink transfer path and wire FastDeploy2 to install and invoke it for app override symlink mirroring. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Renamed the symlink helper experiment to Validation on Samsung A16: The tool was installed under app-private tools: It mirrors the staged tree into |
|
Reran current FastDeploy2 default after Current shape: Device: Samsung Galaxy A16 (
The app launched successfully from the symlinked override tree after the run ( Interpretation:
|
|
Fresh current-strategy comparison table after the latest FastDeploy2 direct-push + Device: Samsung Galaxy A16 (
Notes:
|
Remove FastDeploy3 and FastDeploy4 after narrowing the experiment to legacy FastDeploy plus the direct-push symlink FastDeploy2 path. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Cleaned up the experiment set:
The target strategy set is back to: FastDeploy2 smoke test after cleanup: |
Add an experimental FastDeploy5 strategy which compares a local manifest, pushes only changed files without adb --sync, removes stale staged files, and mirrors the remote staging tree through maui.link. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Added Shape: Usage: -p:_AndroidFastDevStrategy=FastDeploy5Samsung A16 / HelloWorld comparison:
FastDeploy5 is the first adb-based strategy that beats old FastDeploy on the small-change deploy-task cases in this run. It does that by avoiding both bad forms of change discovery:
It only transfers the manifest-detected changed set. |
Add a FastDeploy5 mode which uses manifest data to run rm and ln -sf together in batched run-as shell commands, avoiding the maui.link helper for symlink maintenance. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
FastDeploy5 no-helper experiment: added
Conclusion: |
|
Opened the cleaned-up follow-up PR with the manifest-driven FastDeploy2 implementation: #11698 |
Summary
Draft/WIP experiment for alternate Fast Deployment implementations.
This PR adds two opt-in strategies next to the existing
FastDeploytask:FastDeploy— current implementation using bundledxamarin.sync/xamarin.find/xamarin.cphelper tools.FastDeploy2— standalone task usingadb push -z any --syncto stage files, thenrun-as cp -pintofiles/.__override__.FastDeploy3— standalone task using fake$ANDROID_PRODUCT_OUT+adb sync -z any data, thenrun-as cp -pintofiles/.__override__.The strategy is selected with:
Default remains
FastDeploy.Why
I wanted to explore whether we can simplify Fast Deployment by dropping the custom native helper tools and relying on built-in adb compression/sync support.
Current
FastDeployis fast for tiny one-file updates, but full deploys are dominated byxamarin.synccopy time. The adb-based approaches are much simpler and significantly faster for full transfers in the preliminary measurements below.Implementation notes
FastDeploy2:
adb push --syncFlow:
Stage FastDev files under
$(IntermediateOutputPath)/fastdeploy2.Upload to
/tmp/fastdev2/<package>/<user>using:Diff remote staging vs app override using
find+stat.Copy changed files only with
run-as cp -pintofiles/.__override__.Remove stale override files.
FastDeploy3:
adb sync dataFlow:
Stage FastDev files under a fake product output tree:
Ask adb for changed files with:
Upload via:
Copy only files listed by
adb sync -lplus missing override files intofiles/.__override__.This is why FastDeploy3 stages under
/data/local/tmp/...instead of/tmp/...:adb syncmaps fixed product-output roots like$ANDROID_PRODUCT_OUT/data/...to device/data/....Preliminary benchmark data
Device: Samsung Galaxy A16 (
SM-A165F,R58Y30HZ65V)Project:
samples/HelloWorld/HelloWorld/HelloWorld.DotNet.csprojPayload: ~189-195 FastDev files depending on environment/config files included.
Deploy task totals
push --sync)sync data)Takeaway: adb-based strategies are ~3.6-4x faster for full transfers. The current helper-tool path still wins tiny one-file updates in the initial measurements.
Legacy FastDeploy phase timings
xamarin.synccopyFastDeploy2/FastDeploy3 phase timings before the latest FastDeploy3
sync -loptimizationRaw adb upload comparison
adb push --syncto/tmpadb sync datato/data/local/tmpadb push --syncreports only counts (N pushed, M skipped).adb sync -l datacan list exact changed file names, which is the reason FastDeploy3 is interesting.Hardlink experiment
I also tried to avoid the app-private copy using hardlinks:
cp -Rl /tmp/fastdev2/... files/.__override__failed withCross-device link./data/local/tmp/... -> files/.__override__also failed withCross-device link.run-asfailed withPermission denied.So hardlinks do not appear viable for this optimization path on the tested device.
Caveats / TODO
adb sync -l dataas the changed-file source, but I still need stable follow-up benchmark data after a device disconnect interrupted the clean run.$ANDROID_PRODUCT_OUT/adb sync datais acceptable for product usage or should remain experimental.Validation so far
Focused task builds passed in Debug and Release after the latest parity changes:
Earlier in this branch, the Release SDK was also rebuilt successfully with:
make prepare CONFIGURATION=Release && make all CONFIGURATION=Release