Problem
EmojiManager.create(context, serializer) currently opens the bundled emoticons/emoji.json asset and deserializes the full emoji catalog before the manager can be used. The sample also demonstrates optional eager initialization through AndroidX Startup.
Before changing the storage format or initialization architecture, the project needs a repeatable baseline that measures the current implementation. Without this baseline, later optimisations cannot prove that they improved startup, first use, memory behaviour, or steady-state parsing.
This issue is a prerequisite for the FlatBuffers migration and later representation optimisations.
Goal
Add reproducible AndroidX Benchmark coverage for the current implementation and publish the baseline results in the repository.
The benchmark suite must answer these questions:
- What is the app startup cost when Emojify is linked but unused?
- What additional startup cost is introduced by eager AndroidX Startup initialization?
- What is the first-use cost when
EmojiManager is initialized lazily?
- What is the cost of deserializing the bundled JSON catalog?
- What is the cost of first construction of the lazy Unicode trie, shortcode index, and tag index?
- What is the steady-state cost of the main parsing and lookup operations after all lazy structures are warm?
- What memory and allocation differences are observable between cold creation, first use, and warm repeated use?
Scope
1. Benchmark structure
Create dedicated benchmark infrastructure rather than placing benchmark-only code in production sources.
Use AndroidX Macrobenchmark for application startup and user-visible first-use scenarios.
Use AndroidX Microbenchmark for library-level operations that can be isolated from Activity startup.
Follow the repository's existing Gradle conventions. If the current convention plugins cannot configure benchmark modules, extend them narrowly and document why. Do not introduce unrelated build-system refactors.
2. Startup scenarios
Provide deterministic benchmark variants or equivalent test fixtures for all of the following:
- Control: app launches with Emojify on the classpath but without creating
EmojiManager.
- Eager: app launches with the current AndroidX Startup
EmojiInitializer path enabled.
- Lazy: app launches without initializing Emojify, then initializes
EmojiManager on the first explicit Emoji operation.
The control and eager scenarios must differ only by the initialization behaviour being measured. Do not compare unrelated UI or application configurations.
Record cold-start results for each scenario using the same device or emulator configuration and the same build type.
3. Library-level measurements
At minimum benchmark:
EmojiManager.create(context, KotlinxDeserializer())
- equivalent creation with Gson and Moshi if those serializer modules are still supported by the current branch
- first
getByUnicode(...) call, including lazy trie construction
- warm
getByUnicode(...) lookup
- first
getForShortCode(...) call, including lazy shortcode index construction
- warm shortcode lookup
- first
getForTag(...) call, including lazy tag index construction
- warm tag lookup
parseToUnicode(...)
parseToAliases(...)
parseToHtmlDecimal(...)
parseToHtmlHexadecimal(...)
extractEmojis(...)
removeAllEmojis(...)
Use fixed representative inputs committed to the benchmark fixtures. Include at least:
- short text with no emoji
- short text with one emoji
- mixed text with several common emoji
- text containing Fitzpatrick modifiers
- text containing multi-code-point and ZWJ emoji sequences
- a longer mixed-content input representative of a feed post or comment
Do not generate random input during benchmark execution.
4. Measurement discipline
For every benchmark result record:
- device or emulator model
- Android API level
- ABI
- build variant
- minification state
- benchmark mode and iteration configuration
- library commit SHA
- serializer backend where applicable
Warm-up and measured iterations must be controlled by the benchmark framework rather than custom sleep loops or ad hoc timing with System.nanoTime().
Do not compare debug builds when drawing performance conclusions. Use an optimised benchmarkable or release-equivalent target configuration.
5. Baseline report
Commit a baseline report under docs/benchmarks/.
The report must contain:
- exact commit SHA measured
- environment metadata
- benchmark commands
- raw or linked machine-readable benchmark output
- a concise table of median results
- startup comparison between control, eager, and lazy paths
- first-use versus warm-operation comparisons
- observed memory or allocation data where supported by the selected benchmark tooling
- known limitations
Do not interpret single-run noise as an optimisation opportunity. Report distributions or benchmark framework summaries and call out unstable measurements.
Long-Horizon Execution Protocol
This work may span multiple sessions or agents. Maintain state explicitly.
At the start of each implementation session:
- Read this issue and the latest progress comment.
- Verify the current branch and commit.
- Check which checklist items are already complete before changing code.
- Do not redo completed work unless validation shows it is invalid.
At the end of each implementation session, add or update a progress comment containing:
- Completed: concrete items finished
- Changed: files or modules changed
- Evidence: commands and benchmark/test results
- Pending: next incomplete checklist item
- Blockers: unresolved decisions or failures
Never mark a phase complete without reproducible evidence.
Implementation Checklist
Acceptance Criteria
This issue is complete only when:
- Control, eager, and lazy startup paths can be measured independently and reproducibly.
- Cold manager creation and first lazy-index construction are measured separately from warm operations.
- The main parser and lookup APIs have steady-state microbenchmarks.
- Benchmark inputs and environment metadata are committed and deterministic.
- A baseline report exists under
docs/benchmarks/ and identifies the exact measured commit.
- The benchmark suite can be rerun after future storage changes without rewriting the scenarios.
- No production behaviour is changed as part of establishing the baseline.
Non-Goals
- Do not migrate the bundled catalog away from JSON in this issue.
- Do not remove supported serializer backends in this issue.
- Do not redesign
EmojiManager public APIs in this issue.
- Do not optimise the trie, parser,
htmlDec, or htmlHex representation in this issue.
- Do not declare performance targets before the baseline exists.
Follow-Up Dependency
The FlatBuffers migration must use this benchmark suite as its before/after evidence and must not establish a new incompatible benchmark methodology solely to make the migrated implementation appear faster.
Problem
EmojiManager.create(context, serializer)currently opens the bundledemoticons/emoji.jsonasset and deserializes the full emoji catalog before the manager can be used. The sample also demonstrates optional eager initialization through AndroidX Startup.Before changing the storage format or initialization architecture, the project needs a repeatable baseline that measures the current implementation. Without this baseline, later optimisations cannot prove that they improved startup, first use, memory behaviour, or steady-state parsing.
This issue is a prerequisite for the FlatBuffers migration and later representation optimisations.
Goal
Add reproducible AndroidX Benchmark coverage for the current implementation and publish the baseline results in the repository.
The benchmark suite must answer these questions:
EmojiManageris initialized lazily?Scope
1. Benchmark structure
Create dedicated benchmark infrastructure rather than placing benchmark-only code in production sources.
Use AndroidX Macrobenchmark for application startup and user-visible first-use scenarios.
Use AndroidX Microbenchmark for library-level operations that can be isolated from Activity startup.
Follow the repository's existing Gradle conventions. If the current convention plugins cannot configure benchmark modules, extend them narrowly and document why. Do not introduce unrelated build-system refactors.
2. Startup scenarios
Provide deterministic benchmark variants or equivalent test fixtures for all of the following:
EmojiManager.EmojiInitializerpath enabled.EmojiManageron the first explicit Emoji operation.The control and eager scenarios must differ only by the initialization behaviour being measured. Do not compare unrelated UI or application configurations.
Record cold-start results for each scenario using the same device or emulator configuration and the same build type.
3. Library-level measurements
At minimum benchmark:
EmojiManager.create(context, KotlinxDeserializer())getByUnicode(...)call, including lazy trie constructiongetByUnicode(...)lookupgetForShortCode(...)call, including lazy shortcode index constructiongetForTag(...)call, including lazy tag index constructionparseToUnicode(...)parseToAliases(...)parseToHtmlDecimal(...)parseToHtmlHexadecimal(...)extractEmojis(...)removeAllEmojis(...)Use fixed representative inputs committed to the benchmark fixtures. Include at least:
Do not generate random input during benchmark execution.
4. Measurement discipline
For every benchmark result record:
Warm-up and measured iterations must be controlled by the benchmark framework rather than custom sleep loops or ad hoc timing with
System.nanoTime().Do not compare debug builds when drawing performance conclusions. Use an optimised benchmarkable or release-equivalent target configuration.
5. Baseline report
Commit a baseline report under
docs/benchmarks/.The report must contain:
Do not interpret single-run noise as an optimisation opportunity. Report distributions or benchmark framework summaries and call out unstable measurements.
Long-Horizon Execution Protocol
This work may span multiple sessions or agents. Maintain state explicitly.
At the start of each implementation session:
At the end of each implementation session, add or update a progress comment containing:
Never mark a phase complete without reproducible evidence.
Implementation Checklist
EmojiManagerinitialization behaviour and supported serializer modules.docs/benchmarks/baseline report.Acceptance Criteria
This issue is complete only when:
docs/benchmarks/and identifies the exact measured commit.Non-Goals
EmojiManagerpublic APIs in this issue.htmlDec, orhtmlHexrepresentation in this issue.Follow-Up Dependency
The FlatBuffers migration must use this benchmark suite as its before/after evidence and must not establish a new incompatible benchmark methodology solely to make the migrated implementation appear faster.