Skip to content

Reduce coupon barcode CPU while preserving recognition - #533

Merged
Szer merged 3 commits into
mainfrom
perf/coupon-barcode-decoding
Sep 28, 2026
Merged

Szer merged 3 commits into
mainfrom
perf/coupon-barcode-decoding

Conversation

@Szer

@Szer Szer commented Sep 28, 2026 •

Copy link
Copy Markdown
Owner

Difficult coupon photos spend seconds in the synchronous barcode search before reaching text OCR. Run ZXing-C++ on grayscale pixels and cropped views first, then retain the managed recovery search with reusable luminance buffers and redundant inversion disabled. Native library failures safely use the managed fallback. Native views use bounded spans and a scoped managed pin lease, with no unsafe code or raw pointers in the adapter.

A paired CPU-only benchmark over all 2,201 downloaded coupon images reduces total CPU by 47.8%, and CPU for the 20 control no-reads by 47.2%. Overall p99 elapsed parsing falls from 2.53 s to 0.66 s. A throttled ARM64 container using the production runtime base reduces one difficult image from 28.9 s / 7.23 CPU s to 14.7 s / 3.67 CPU s.

Reviewed-label result Control New pipeline
Correct barcode 2,174 2,181
Wrong barcode 7 1
No read 20 19

No previously correct result is lost. All 421 holdout outputs are unchanged. Labels include reviewed disagreements and approved OCR consensus for missing values; this positive-only corpus cannot establish a true-negative rate. Private images, labels and benchmark observations stay outside the repository.

Validation: 264 integration tests and 26 OCR/behavior tests pass without paid OCR calls; ARM64 native dependencies and missing-library fallback are exercised separately. New tests assert barcode recognition at four orientations and no invented barcode on blank images.

A separate binding-only upgrade check (ImageSharp binding 0.16.18 → 0.16.20, same ZXing.Net 0.16.11 core) produces identical results on all 2,201 images and effectively identical CPU totals (112.55 s versus 112.45 s). The checked-span adapter preserves all corpus outputs and passes 64 repeated decodes during 14,095 compacting garbage collections.

On 2,144 control first-attempt successes, a balanced three-repeat comparison isolates the native-stage cost: happy-path p95 falls from 9.35 ms (optimized managed only) to 8.43 ms (native + managed fallback), with median latency 4.41 ms → 3.81 ms. Three individual images add 12–19 ms because of native crops/fallback. These are local CPU-only measurements; ARM64 happy-path p95 is not established by the single-image ARM spot check.

The snapshot race-test harness runs parked loads on workers, bounds its gates and releases them on concurrent-operation failure. This prevents synchronous database completion from blocking the test before it can release the parked fold. A deterministic scheduling repro and all 34 BotInfra tests pass locally and on ARM64 CI. All PR checks pass; the Vahter job completes in 5m52s.

@Szer
Szer enabled auto-merge (squash) September 28, 2026 11:23
@Szer
Szer disabled auto-merge September 28, 2026 11:30
@Szer
Szer merged commit 49a6e35 into main Sep 28, 2026
8 checks passed
@Szer
Szer deleted the perf/coupon-barcode-decoding branch September 28, 2026 11:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant