bcquality/microsoft/knowledge/performance/use-isempty-for-existence-checks.md
Jesper Schulz-Wedde 32c40bbf1d Seed performance knowledge corpus (22 articles + AL samples)
Converts an existing performance-review prompt into 22 atomic
knowledge articles under microsoft/knowledge/performance/, each
paired with AL samples under samples/performance/<slug>/ demonstrating
the anti-pattern and/or the best practice. The full set seeds the
corpus the microsoft/skills/al-performance-review leaf skill matches
against and validates the READ knowledge-file format end-to-end.

Every article conforms to the READ contract: six required frontmatter
fields, Description always present, no fenced code blocks, sample
code referenced by repo-relative path. Each article is marked with a
blockquote 'Seed article' note so domain stewards can extend or
restructure them freely.

Articles (ordered by concern area):

Database query efficiency
- use-findset-with-next (AA0181)
- avoid-findfirst-with-next (AA0233)
- only-fetch-records-you-use (AA0175)
- use-findset-readonly-by-default
- use-setloadfields-for-partial-records
- use-addloadfields-in-report-layouts
- use-calcsums-to-aggregate-filtered-sets (file: use-calcsums-for-flowfield-totals.md)
- avoid-calcfields-in-loops
- add-sift-keys-for-flowfields (AA0232)
- use-isempty-for-existence-checks

Filter and key optimization
- filter-before-find
- set-current-key-to-match-filters

Temporary tables and transactions
- use-temporary-tables-for-intermediate-data
- keep-transaction-scope-short
- avoid-user-interaction-in-transactions
- avoid-commit-inside-loops

Record operations
- prefer-get-for-primary-key-lookups
- use-insert-false-when-skipping-triggers
- prefer-direct-record-over-recordref

Strings, codeunits, events
- use-strsubstno-for-message-formatting
- use-single-instance-codeunits-for-caching
- keep-event-subscribers-lightweight

samples/README.md documents the sample-folder convention and makes
clear the samples are demonstration-only, not derived from BC base
application source, with unique object IDs in the 50100-50199 range.

Rubber-duck pass caught: a misleading good.al in avoid-calcfields-in-loops
(fixed by switching to a hoistable CalcFields scenario), an invalid
event subscriber signature in keep-event-subscribers-lightweight
(fixed by adding var xRec), normative guidance leaked into the
Description of use-findset-readonly-by-default (moved to Anti Pattern),
a missing sample pair for keep-transaction-scope-short (added), and
muddy FlowField/CalcSums framing (retitled and clarified).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-17 13:23:34 +02:00

1.2 KiB

bc-version domain keywords technologies countries application-area
26..28
performance
isempty
count
findfirst
existence
al
w1
all

Use IsEmpty for existence checks

Seed article. Converted from an existing performance-review prompt to bootstrap the BCQuality performance corpus. Domain stewards should expand, restructure, and refine as needed.

Description

IsEmpty is the cheapest way to answer whether at least one row matches the current filters. It short-circuits at the first match and never hydrates a record. Count() scans and counts the entire set; FindFirst fetches a full row just to be discarded.

Best Practice

Use if not Rec.IsEmpty() then ... for existence checks. Reserve Count for cases where the exact number of rows is needed, and FindFirst for cases where you actually want the row's field values.

See sample: samples/performance/use-isempty-for-existence-checks/good.al.

Anti Pattern

if Rec.Count() > 0 iterates the whole set just to answer a yes/no question. if Rec.FindFirst() then loads an entire row of data the caller never reads.

See sample: samples/performance/use-isempty-for-existence-checks/bad.al.