This repository provides two run paths:
- iPhone app path for real on-device SDK testing.
- CLI path for macOS command-line runs.
Both paths use the same core benchmark pipeline in Sources/BenchmarkCore.
Project context and parameter rationale: docs/requirements/project-requirements.md.
Use this path when you want to run real ML Kit or Dynamsoft scanning on a physical iPhone.
cd BenchmarkApp
pod install
open BenchmarkApp.xcworkspaceAlways open .xcworkspace (not .xcodeproj).
- In Xcode, open target BenchmarkApp.
- Go to Signing & Capabilities.
- Enable Automatically manage signing.
- Select your Apple Team.
- Use a unique bundle identifier if needed.
- Select your iPhone as run destination.
- Press Run.
At runtime, the app resolves dataset directories in this order:
AppBundle/annotationsand videos inAppBundle/.Documents/benchmark-dataset/annotationsand videos inDocuments/benchmark-dataset/.
If neither is found, the app reports a clear dataset-not-found error in the log view.
Option A: Bundle files into app target
- Drag
annotations/and your.mp4clips into Xcode under the app target. - Enable Copy items if needed and add to target BenchmarkApp.
Option B: Copy into app Documents via Finder (recommended for larger datasets)
- Build and install app once.
- Connect iPhone to Mac.
- Finder -> iPhone -> Files -> BenchmarkApp.
- Copy folder structure:
benchmark-dataset/
annotations/
clip1.csv
clip2.csv
clip1.mp4
clip2.mp4
The app does not use command-line flags. Parameters are set via UI and code defaults in BenchmarkApp/BenchmarkApp/BenchmarkViewController.swift.
| Parameter | Values | Current Default | Where to set it | Meaning |
|---|---|---|---|---|
engine |
mlkit-real, dynamsoft-baseline-parity, dynamsoft-tuned-parity, dynamsoft-tuned-nativesupplemental |
mlkit-real |
Engine picker UI | Selects detector backend |
phase |
baseline, tuned |
baseline |
Settings UI | Benchmark phase label |
track |
parity, nativeSupplemental |
parity |
Settings UI | Comparison track type |
clipTimeoutSeconds |
any Double > 0 |
120 |
Settings UI | Max seconds per clip before fail |
samplingPolicy.everyNFrames |
any Int >= 1 |
5 |
Settings UI | Sample every Nth frame |
samplingPolicy.maxFrames |
any Int >= 1 |
60 |
Settings UI | Max sampled frames per clip |
deviceModel |
free text | UIDevice.current.model |
Code (baseConfig) |
Device tag in export metadata |
osVersion |
free text | UIDevice.current.systemVersion |
Code (baseConfig) |
OS tag in export metadata |
runId |
free text/UUID | auto UUID | Code (baseConfig) |
Unique run identifier |
- Launch app on iPhone.
- Pick
enginein the picker. - Tap the gear icon (⚙️) to open Settings and adjust
phase,track, sampling, and timeout. - Tap Run Benchmark (or Run All to run every engine preset sequentially).
Dynamsoft engine presets lock phase and track automatically. ML Kit leaves them configurable.
Outputs are written to app Documents:
benchmark-out/benchmark.jsonbenchmark-out/benchmark.csv
Use this path for scriptable terminal runs on macOS.
swift run BenchmarkCLI \
--annotations /path/to/annotations \
--videos /path/to/videos \
--output /path/to/out \
--engine mlkit-mock \
--phase baseline \
--track parity| Flag | Required | Allowed Values | Default | Meaning |
|---|---|---|---|---|
--annotations <dir> |
Yes | existing directory path | none | Directory containing annotation CSV files |
--videos <dir> |
Yes | existing directory path | none | Directory containing MP4 clips |
--output <dir> |
Yes | directory path | none | Output directory for exports |
--engine <name> |
No | mlkit-mock, dynamsoft-mock, mlkit-real, dynamsoft-real |
mlkit-mock |
Selects detector backend |
--phase <value> |
No | baseline, tuned |
baseline |
Benchmark phase label |
--track <value> |
No | parity, nativeSupplemental |
parity |
Comparison track type |
--device <name> |
No | free text | Mac |
Device tag in metadata |
--os <name> |
No | free text | macOS |
OS tag in metadata |
--help |
No | n/a | n/a | Prints CLI usage and exits |
mlkit-mockanddynamsoft-mock: deterministic mock detections for pipeline validation.mlkit-real: requires ML Kit frameworks linked on an iOS target.dynamsoft-real: requires Dynamsoft SDK + license wiring for host context.
The CLI writes to your --output directory:
benchmark.jsonbenchmark.csv
| Column | Description |
|---|---|
runId |
Unique run identifier |
sdk |
mlkit or dynamsoft |
phase |
baseline or tuned |
trackType |
parity or nativeSupplemental |
directlyComparable |
true for parity track, false for nativeSupplemental |
deviceModel |
Device tag from run metadata |
osVersion |
OS tag from run metadata |
datasetHash |
Hash of the dataset used |
configHash |
Hash of the run configuration |
clipId |
Stem filename of the clip |
succeeded |
Whether the clip completed without error |
errorDescription |
Error message if clip failed |
uniqueDetections |
Count of unique barcode texts detected |
expectedTexts |
Pipe-delimited ground-truth barcode texts |
detectedTexts |
Pipe-delimited detected barcode texts |
expectedFormats |
Pipe-delimited expected symbologies (e.g. CODE_128|QR_CODE) |
detectedFormats |
Pipe-delimited detected symbologies |
recall |
Fraction of expected codes found (0–1) |
precision |
Fraction of detected codes that are correct (0–1) |
meanLatencyMs |
Mean decode latency in milliseconds |
compositeScore |
Weighted score: 50% recall + 30% precision + 20% normalized speed |