From ab8e973d7e60e11483d141e95f05efd56aea1186 Mon Sep 17 00:00:00 2001 From: vinishavathwani Date: Mon, 18 May 2026 20:26:10 +0530 Subject: [PATCH 1/6] Update links, minor fixes for R8 skill --- performance/r8-analyzer/SKILL.md | 36 +-- .../references/CONFIGURATION-ANALYZER.md | 302 ++++++++++++++++++ .../r8-analyzer/references/REPORT_FORMAT.md | 57 ++++ 3 files changed, 377 insertions(+), 18 deletions(-) create mode 100644 performance/r8-analyzer/references/CONFIGURATION-ANALYZER.md create mode 100644 performance/r8-analyzer/references/REPORT_FORMAT.md diff --git a/performance/r8-analyzer/SKILL.md b/performance/r8-analyzer/SKILL.md index c384a83..65966fd 100644 --- a/performance/r8-analyzer/SKILL.md +++ b/performance/r8-analyzer/SKILL.md @@ -16,15 +16,15 @@ metadata: - optimization --- -## Step 1. Setup and Configuration Check +## Step 1. Setup and configuration check - Inspect `build.gradle`, `build.gradle.kts`, and `gradle.properties`. -- Use [/references/CONFIGURATION.md](references/CONFIGURATION.md) to identify missing optimizations. +- Use [references/CONFIGURATION.md](references/CONFIGURATION.md) to identify missing optimizations. - **AGP** : If \< 9.0, suggest migration to 9.0 for [build time improvement performance](references/android/topic/performance/app-optimization/enable-app-optimization.md) -- **Full Mode** : Verify `android.enableR8.fullMode=false` is removed from gradle.properties. +- **Full mode** : Verify `android.enableR8.fullMode=false` is removed from gradle.properties. -## Step 2. Analysis Path Selection +## Step 2. Analysis path selection - Inspect `build.gradle`, `build.gradle.kts`, and `gradle.properties` and `libs.versions.toml` to @@ -34,24 +34,24 @@ metadata: - **If R8 \< 9.3.7-dev** : Proceed to **Path B (Heuristic)**. -### Path A: Quantitative Data Generation (R8 \>= 9.3.7-dev) +### Path A: Quantitative data generation (R8 \>= 9.3.7-dev) -- **Check Requirements** : Python and `protobuf` package are mandatory. -- **Generate and Analyze** : You MUST run the shell commands described in `[/references/CONFIGURATION-ANALYZER.md][7]` to generate the proto file using R8 configuration analyzer, convert it to json and analyze the result. +- **Check requirements** : Python and `protobuf` package are mandatory. +- **Generate and analyze** : You MUST run the shell commands described in [references/CONFIGURATION-ANALYZER.md](references/CONFIGURATION-ANALYZER.md) to generate the proto file using R8 configuration analyzer, convert it to json and analyze the result. - **Report**: Rely entirely on the generated file analysis.txt for scores and rule impact metrics. Proceed to Step 3. -### Path B: Heuristic Evaluation and Recommendation (R8 \< 9.3.7-dev) +### Path B: Heuristic evaluation and recommendation (R8 \< 9.3.7-dev) *(Use ONLY if quantitative data generation is not possible)* -- **Manual Evaluation** : Inspect `proguard-rules.pro`. -- **Library Check** : Compare rules against [/references/REDUNDANT-RULES.md](references/REDUNDANT-RULES.md) .Suggest **Remove** for bundled rules. -- **Custom Rule Check** : Use [/references/KEEP-RULES-IMPACT-HIERARCHY.md](references/KEEP-RULES-IMPACT-HIERARCHY.md) and [/references/REFLECTION-GUIDE.md](references/REFLECTION-GUIDE.md) to prioritize and evaluate. Suggest **Refine** for broad rules (e.g., package-wide). +- **Manual evaluation** : Inspect `proguard-rules.pro`. +- **Library check** : Compare rules against [references/REDUNDANT-RULES.md](references/REDUNDANT-RULES.md) .Suggest **Remove** for bundled rules. +- **Custom rule check** : Use [references/KEEP-RULES-IMPACT-HIERARCHY.md](references/KEEP-RULES-IMPACT-HIERARCHY.md) and [references/REFLECTION-GUIDE.md](references/REFLECTION-GUIDE.md) to prioritize and evaluate. Suggest **Refine** for broad rules (e.g., package-wide). - **Validation** : Suggest Macrobenchmark tests using [ui automator](references/android/training/testing/other-components/ui-automator.md) for any proposed changes. Proceed to Step 3. -## Step 3. Report Generation +## Step 3. Report generation -- **Format** : Follow `[/references/REPORT_FORMAT.md][8]` strictly. +- **Format** : Follow [references/REPORT_FORMAT.md](references/REPORT_FORMAT.md) strictly. - **Input**: Extract metrics (Scores, Impacts, Example Classes) directly from generated file analysis.txt if using Path A, or from manual findings if using Path B. @@ -61,12 +61,12 @@ metadata: Do NOT output conversational filler (e.g., "Here is your report..."). Do NOT provide recommendations, next steps, or any other text outside of the sections defined in - `[/references/REPORT_FORMAT.md][8]` + [references/REPORT_FORMAT.md](references/REPORT_FORMAT.md) Do NOT mention the path used for analysis of the configuration ## Constraints -- **Strict Output Limit**: The final output MUST strictly be the Markdown report and nothing else. -- **No Code Changes**: Research and suggest only; Do not modify files. -- **No Redundancy**: Do not explain R8 benefits or reference skill internal files in the report. -- **Focus**: Omit sections (e.g., Subsumed Rules, Configuration) if no issues or items are found. +- **Strict output limit**: The final output MUST strictly be the Markdown report and nothing else. +- **No code changes**: Research and suggest only; Do not modify files. +- **No redundancy**: Do not explain R8 benefits or reference skill internal files in the report. +- **Focus**: Omit sections (e.g., Subsumed Rules, Configuration) if no issues or items are found. \ No newline at end of file diff --git a/performance/r8-analyzer/references/CONFIGURATION-ANALYZER.md b/performance/r8-analyzer/references/CONFIGURATION-ANALYZER.md new file mode 100644 index 0000000..6e30d37 --- /dev/null +++ b/performance/r8-analyzer/references/CONFIGURATION-ANALYZER.md @@ -0,0 +1,302 @@ +# CONFIGURATION ANALYZER DATA GENERATION + +On each step, keep the user informed of the progress by displaying the output. + +### 1. Requirements + +- R8 Version: 9.3.7-dev or later + +### 2. Generate proto + +The report and files must be generated at `{project_root}/tmp/r8analysis`. If the folder +is not present, create it. For example: + +```bash +mkdir -p "$PWD/tmp/r8analysis" +``` + +### 3. Remove existing files + +To make sure that this invocation doesn't source data from previous runs, +remove the intermediate files `keepruleradius.json` and `analysis_result.txt` +and remove the proto files in the `{project_root}/tmp/r8analysis folder`. Example bash commands: + +```bash +# Remove the intermediate JSON and the directory containing protobuf files +rm tmp/r8analysis/keepruleradius.json +rm tmp/r8analysis/*.pb + +# Copy the previous result to history before deleting the analysis +if [ -f tmp/r8analysis/analysis_result.txt ]; +then cat tmp/r8analysis/analysis_result.txt > tmp/r8analysis/history.txt && + rm tmp/r8analysis/analysis_result.txt; fi + + +``` +### 4. Generate configuration analyzer report + +Run the R8 enabled build with the system property +"-Dcom.android.tools.r8.dumpkeepradiustodirectory=$PWD/tmp/r8analysis" +to generate Configuration Analyzer report + +```bash +./gradlew assembleRelease \ + -Dcom.android.tools.r8.dumpkeepradiustodirectory=$PWD/tmp/r8analysis +``` + +### 5. Convert to JSON + +To convert the generated protobuf files in `{project_root}/tmp/r8analysis` into json, +run the following script. The json must be generated in `{project_root}/tmp/r8analysis`. +Ensure `keep_radius_pb2.py` (from Step 10) is in the same directory. + +```python +import sys +import os +import glob +from google.protobuf import json_format +import keep_radius_pb2 + +def convert_pb_to_json(input_pb_path, output_json_path): + bundle = keep_radius_pb2.BlastRadiusContainer() + + try: + with open(input_pb_path, "rb") as pb_file: + binary_data = pb_file.read() + except Exception as e: + print(f"Error reading file {input_pb_path}: {e}", file=sys.stderr) + return False + + try: + bundle.ParseFromString(binary_data) + except Exception as e: + print(f"Error parsing protobuf: {e}", file=sys.stderr) + return False + + try: + json_string = json_format.MessageToJson( + bundle, + always_print_fields_with_no_presence=True, + preserving_proto_field_name=True, + indent=4 + ) + with open(output_json_path, "w", encoding="utf-8") as json_file: + json_file.write(json_string) + return True + except Exception as e: + print(f"Error writing JSON: {e}", file=sys.stderr) + return False + +if __name__ == "__main__": + input_pb = sys.argv[1] if len(sys.argv) > 1 else None + if not input_pb: + pb_files = glob.glob("tmp/r8analysis/*.pb") + if not pb_files: + print("Error: No .pb file found in tmp/r8analysis", file=sys.stderr) + sys.exit(1) + input_pb = sorted(pb_files)[-1] # Use the most recent one + output_json = sys.argv[2] if len(sys.argv) > 2 else "tmp/r8analysis/keepruleradius.json" + if not convert_pb_to_json(input_pb, output_json): + sys.exit(1) +``` + +### 6. Analyze + +Run the following analysis script on the generated JSON to get the impact of +the keep rules and sort it. + +```python +import json, sys + +def analyze(path): + try: + with open(path, 'r') as f: + d = json.load(f) + except Exception as e: + print(f"Error loading JSON: {e}") + return + + # Build reference map + c_map = {c.get('id'): set(c.get('constraints', [])) for c in d.get('keep_constraints_table', [])} + r_map = {r.get('id'): c_map.get(r.get('constraints_id'), set()) for r in d.get('keep_rule_blast_radius_table', [])} + + tot_opt = tot_obf = tot_shr = tot_items = 0 + + # Tally constraints across all kept items + for tbl in ('kept_class_info_table', 'kept_field_info_table', 'kept_method_info_table'): + for i in d.get(tbl, []): + tot_items += 1 + kb = i.get('kept_by', []) + if any('DONT_OPTIMIZE' in r_map.get(r, set()) for r in kb): tot_opt += 1 + if any('DONT_OBFUSCATE' in r_map.get(r, set()) for r in kb): tot_obf += 1 + if any('DONT_SHRINK' in r_map.get(r, set()) for r in kb): tot_shr += 1 + + # Find denominator + bi = d.get('build_info', {}) + live = sum(int(bi.get(k, 0)) for k in ('live_class_count', 'live_field_count', 'live_method_count')) + denom = live if live > 0 else tot_items + + # Check for globals + globals_src = [g.get('source', '').lower() for g in d.get('global_keep_rule_blast_radius_table', [])] + def score(cnt, flag): + if any(flag in src for src in globals_src): return 0.0 + return max(0.0, 100.0 - ((cnt / denom * 100) if denom > 0 else 0)) + + result = [ + f"Optimization Score: {score(tot_opt, '-dontoptimize'):.2f}%", + f"Obfuscation Score: {score(tot_obf, '-dontobfuscate'):.2f}%", + f"Shrinking Score: {score(tot_shr, '-dontshrink'):.2f}%" + ] + for line in result: + print(line) + with open("tmp/r8analysis/analysis_result.txt", "w") as f: + f.write("\n".join(result)) + +if __name__ == "__main__": + path = sys.argv[1] if len(sys.argv) > 1 else "tmp/r8analysis/keepruleradius.json" + analyze(path) +``` +Outputs `analysis_result.txt` containing scores and rule impacts. + +### 7. Report impactful rules + +Identify the keep rules with the highest impact and the subsumed rules using +the following script. + +```python +import json, sys + +def report(path): + try: + with open(path, 'r') as f: + data = json.load(f) + except Exception as e: + print(f"Error loading JSON: {e}") + return + + # Calculate denominator for percentage + bi = data.get('build_info', {}) + live = sum(int(bi.get(k, 0)) for k in ('live_class_count', 'live_field_count', 'live_method_count')) + denom = live if live > 0 else sum(len(data.get(tbl, [])) for tbl in ('kept_class_info_table', 'kept_field_info_table', 'kept_method_info_table')) + + processed = [] + for r in data.get('keep_rule_blast_radius_table', []): + br = r.get('blast_radius', {}) + c, f, m = len(br.get('class_blast_radius', [])), len(br.get('field_blast_radius', [])), len(br.get('method_blast_radius', [])) + impact = c + f + m + if impact == 0: + continue + impact_pct = (impact / denom * 100) if denom > 0 else 0.0 + processed.append({ + 'id': r.get('id'), + 'source': r.get('source'), + 'impact': impact, + 'impact_pct': f"{impact_pct:.2f}%", + 'classes': c, + 'fields': f, + 'methods': m, + 'subsumed_by': br.get('subsumed_by', []) + }) + + processed.sort(key=lambda x: x['impact'], reverse=True) + + # Output JSON for the agent to fetch and process + print(json.dumps({ + "top_5_impact_keep_rules": [r for r in processed if not r['subsumed_by']][:5], + "subsumed": [r for r in processed if r['subsumed_by']] + }, indent=2)) + +if __name__ == "__main__": + report("tmp/r8analysis/keepruleradius.json") +``` +Add this data to the `analysis_result.txt` with the top impactful rules and +subsumed rules. + +### 8. Compare with previous report + +If `tmp/r8analysis/history.txt` exists, use the following script to compare the +previous run. Use this to compare with the current values + +### 9. Remove generated files + +After the final report and analysis results are generated, +remove the intermediate files `keepruleradius.json` and `analysis_result.txt` +and remove the proto files in "tmp/r8analysis" folder + +```bash +rm tmp/r8analysis/keepruleradius.json +rm tmp/r8analysis/*.pb +``` + +### 10. Protobuf Python bindings + +The following script `keep_radius_pb2.py` is required by the + conversion script in Step 5. + +```python +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import runtime_version as _runtime_version +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +_runtime_version.ValidateProtobufRuntimeVersion( + _runtime_version.Domain.PUBLIC, + 6, + 33, + 4, + '', + 'keep_radius.proto' +) +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x11keep_radius.proto\x12&com.android.tools.r8.blastradius.proto\"\x9f\x02\n\x13KeepRuleBlastRadius\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x0e\n\x06source\x18\x02 \x01(\t\x12\x16\n\x0e\x63onstraints_id\x18\x03 \x01(\x05\x12\x46\n\x06origin\x18\x04 \x01(\x0b\x32\x36.com.android.tools.r8.blastradius.proto.TextFileOrigin\x12I\n\x0c\x62last_radius\x18\x05 \x01(\x0b\x32\x33.com.android.tools.r8.blastradius.proto.BlastRadius\x12\x41\n\x04tags\x18\x06 \x03(\x0e\x32\x33.com.android.tools.r8.blastradius.proto.KeepRuleTag\"w\n\x0b\x42lastRadius\x12\x13\n\x0bsubsumed_by\x18\x01 \x03(\x05\x12\x1a\n\x12\x63lass_blast_radius\x18\x02 \x03(\x05\x12\x1a\n\x12\x66ield_blast_radius\x18\x03 \x03(\x05\x12\x1b\n\x13method_blast_radius\x18\x04 \x03(\x05\"\x7f\n\x19GlobalKeepRuleBlastRadius\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x0e\n\x06source\x18\x02 \x01(\t\x12\x46\n\x06origin\x18\x03 \x01(\x0b\x32\x36.com.android.tools.r8.blastradius.proto.TextFileOrigin\"j\n\x0fKeepConstraints\x12\n\n\x02id\x18\x01 \x01(\x05\x12K\n\x0b\x63onstraints\x18\x02 \x03(\x0e\x32\x36.com.android.tools.r8.blastradius.proto.KeepConstraint\"`\n\rKeptClassInfo\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x1a\n\x12\x63lass_reference_id\x18\x02 \x01(\x05\x12\x16\n\x0e\x66ile_origin_id\x18\x03 \x01(\x05\x12\x0f\n\x07kept_by\x18\x04 \x03(\x05\"`\n\rKeptFieldInfo\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x1a\n\x12\x66ield_reference_id\x18\x02 \x01(\x05\x12\x16\n\x0e\x66ile_origin_id\x18\x03 \x01(\x05\x12\x0f\n\x07kept_by\x18\x04 \x03(\x05\"b\n\x0eKeptMethodInfo\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x1b\n\x13method_reference_id\x18\x02 \x01(\x05\x12\x16\n\x0e\x66ile_origin_id\x18\x03 \x01(\x05\x12\x0f\n\x07kept_by\x18\x04 \x03(\x05\"a\n\x0e\x46ieldReference\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x1a\n\x12\x63lass_reference_id\x18\x02 \x01(\x05\x12\x19\n\x11type_reference_id\x18\x03 \x01(\x05\x12\x0c\n\x04name\x18\x04 \x01(\t\"c\n\x0fMethodReference\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x1a\n\x12\x63lass_reference_id\x18\x02 \x01(\x05\x12\x1a\n\x12proto_reference_id\x18\x03 \x01(\x05\x12\x0c\n\x04name\x18\x04 \x01(\t\"K\n\x0eProtoReference\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x15\n\rparameters_id\x18\x02 \x01(\x05\x12\x16\n\x0ereturn_type_id\x18\x03 \x01(\x05\"4\n\rTypeReference\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x17\n\x0fjava_descriptor\x18\x02 \x01(\t\";\n\x11TypeReferenceList\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x1a\n\x12type_reference_ids\x18\x02 \x03(\x05\"\x9f\x01\n\nFileOrigin\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x10\n\x08\x66ilename\x18\x02 \x01(\t\x12Q\n\x10maven_coordinate\x18\x03 \x01(\x0b\x32\x37.com.android.tools.r8.blastradius.proto.MavenCoordinate\x12 \n\x18provided_by_build_system\x18\x04 \x01(\x08\"I\n\x14\x43lassFileInJarOrigin\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x16\n\x0e\x66ile_origin_id\x18\x02 \x01(\x05\x12\r\n\x05\x65ntry\x18\x03 \x01(\t\"T\n\x0eTextFileOrigin\x12\x16\n\x0e\x66ile_origin_id\x18\x01 \x01(\x05\x12\x13\n\x0bline_number\x18\x02 \x01(\x05\x12\x15\n\rcolumn_number\x18\x03 \x01(\x05\"U\n\x0fMavenCoordinate\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x10\n\x08group_id\x18\x02 \x01(\t\x12\x13\n\x0b\x61rtifact_id\x18\x03 \x01(\t\x12\x0f\n\x07version\x18\x04 \x01(\t\"\x9a\x01\n\tBuildInfo\x12\x13\n\x0b\x63lass_count\x18\x01 \x01(\x05\x12\x13\n\x0b\x66ield_count\x18\x02 \x01(\x05\x12\x14\n\x0cmethod_count\x18\x03 \x01(\x05\x12\x18\n\x10live_class_count\x18\x04 \x01(\x05\x12\x18\n\x10live_field_count\x18\x05 \x01(\x05\x12\x19\n\x11live_method_count\x18\x06 \x01(\x05\"\xd5\n\n\x14\x42lastRadiusContainer\x12M\n\x11\x66ile_origin_table\x18\x01 \x03(\x0b\x32\x32.com.android.tools.r8.blastradius.proto.FileOrigin\x12\x64\n\x1e\x63lass_file_in_jar_origin_table\x18\x02 \x03(\x0b\x32<.com.android.tools.r8.blastradius.proto.ClassFileInJarOrigin\x12W\n\x16maven_coordinate_table\x18\x03 \x03(\x0b\x32\x37.com.android.tools.r8.blastradius.proto.MavenCoordinate\x12U\n\x15\x66ield_reference_table\x18\x04 \x03(\x0b\x32\x36.com.android.tools.r8.blastradius.proto.FieldReference\x12W\n\x16method_reference_table\x18\x05 \x03(\x0b\x32\x37.com.android.tools.r8.blastradius.proto.MethodReference\x12U\n\x15proto_reference_table\x18\x06 \x03(\x0b\x32\x36.com.android.tools.r8.blastradius.proto.ProtoReference\x12S\n\x14type_reference_table\x18\x07 \x03(\x0b\x32\x35.com.android.tools.r8.blastradius.proto.TypeReference\x12\\\n\x19type_reference_list_table\x18\x08 \x03(\x0b\x32\x39.com.android.tools.r8.blastradius.proto.TypeReferenceList\x12T\n\x15kept_class_info_table\x18\t \x03(\x0b\x32\x35.com.android.tools.r8.blastradius.proto.KeptClassInfo\x12T\n\x15kept_field_info_table\x18\n \x03(\x0b\x32\x35.com.android.tools.r8.blastradius.proto.KeptFieldInfo\x12V\n\x16kept_method_info_table\x18\x0b \x03(\x0b\x32\x36.com.android.tools.r8.blastradius.proto.KeptMethodInfo\x12W\n\x16keep_constraints_table\x18\x0c \x03(\x0b\x32\x37.com.android.tools.r8.blastradius.proto.KeepConstraints\x12\x61\n\x1ckeep_rule_blast_radius_table\x18\r \x03(\x0b\x32;.com.android.tools.r8.blastradius.proto.KeepRuleBlastRadius\x12n\n#global_keep_rule_blast_radius_table\x18\x0e \x03(\x0b\x32\x41.com.android.tools.r8.blastradius.proto.GlobalKeepRuleBlastRadius\x12\x45\n\nbuild_info\x18\x0f \x01(\x0b\x32\x31.com.android.tools.r8.blastradius.proto.BuildInfo*\x1f\n\x0bKeepRuleTag\x12\x10\n\x0cPACKAGE_WIDE\x10\x00*H\n\x0eKeepConstraint\x12\x12\n\x0e\x44ONT_OBFUSCATE\x10\x00\x12\x11\n\rDONT_OPTIMIZE\x10\x01\x12\x0f\n\x0b\x44ONT_SHRINK\x10\x02\x42\x45\n&com.android.tools.r8.blastradius.protoB\x19KeepRuleBlastRadiusProtosP\001\x62\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'keep_radius_pb2', _globals) +if not _descriptor._USE_C_DESCRIPTORS: + _globals['DESCRIPTOR']._loaded_options = None + _globals['DESCRIPTOR']._serialized_options = b'\n&com.android.tools.r8.blastradius.protoB\031KeepRuleBlastRadiusProtosP\001' + _globals['_KEEPRULETAG']._serialized_start = 3332 + _globals['_KEEPRULETAG']._serialized_end = 3363 + _globals['_KEEPCONSTRAINT']._serialized_start = 3365 + _globals['_KEEPCONSTRAINT']._serialized_end = 3437 + _globals['_KEEPRULEBLASTRADIUS']._serialized_start = 62 + _globals['_KEEPRULEBLASTRADIUS']._serialized_end = 349 + _globals['_BLASTRADIUS']._serialized_start = 351 + _globals['_BLASTRADIUS']._serialized_end = 470 + _globals['_GLOBALKEEPRULEBLASTRADIUS']._serialized_start = 472 + _globals['_GLOBALKEEPRULEBLASTRADIUS']._serialized_end = 599 + _globals['_KEEPCONSTRAINTS']._serialized_start = 601 + _globals['_KEEPCONSTRAINTS']._serialized_end = 707 + _globals['_KEPTCLASSINFO']._serialized_start = 709 + _globals['_KEPTCLASSINFO']._serialized_end = 805 + _globals['_KEPTFIELDINFO']._serialized_start = 807 + _globals['_KEPTFIELDINFO']._serialized_end = 903 + _globals['_KEPTMETHODINFO']._serialized_start = 905 + _globals['_KEPTMETHODINFO']._serialized_end = 1003 + _globals['_FIELDREFERENCE']._serialized_start = 1005 + _globals['_FIELDREFERENCE']._serialized_end = 1102 + _globals['_METHODREFERENCE']._serialized_start = 1104 + _globals['_METHODREFERENCE']._serialized_end = 1203 + _globals['_PROTOREFERENCE']._serialized_start = 1205 + _globals['_PROTOREFERENCE']._serialized_end = 1280 + _globals['_TYPEREFERENCE']._serialized_start = 1282 + _globals['_TYPEREFERENCE']._serialized_end = 1334 + _globals['_TYPEREFERENCELIST']._serialized_start = 1336 + _globals['_TYPEREFERENCELIST']._serialized_end = 1395 + _globals['_FILEORIGIN']._serialized_start = 1398 + _globals['_FILEORIGIN']._serialized_end = 1557 + _globals['_CLASSFILEINJARORIGIN']._serialized_start = 1559 + _globals['_CLASSFILEINJARORIGIN']._serialized_end = 1632 + _globals['_TEXTFILEORIGIN']._serialized_start = 1634 + _globals['_TEXTFILEORIGIN']._serialized_end = 1718 + _globals['_MAVENCOORDINATE']._serialized_start = 1720 + _globals['_MAVENCOORDINATE']._serialized_end = 1805 + _globals['_BUILDINFO']._serialized_start = 1808 + _globals['_BUILDINFO']._serialized_end = 1962 + _globals['_BLASTRADIUSCONTAINER']._serialized_start = 1965 + _globals['_BLASTRADIUSCONTAINER']._serialized_end = 3330 +# @@protoc_insertion_point(module_scope) +``` \ No newline at end of file diff --git a/performance/r8-analyzer/references/REPORT_FORMAT.md b/performance/r8-analyzer/references/REPORT_FORMAT.md new file mode 100644 index 0000000..b8aaa9c --- /dev/null +++ b/performance/r8-analyzer/references/REPORT_FORMAT.md @@ -0,0 +1,57 @@ +# R8 Analysis Report Template + +## 1. Configuration + +*(Optional section for the report, omit if no relevant findings are present.)* + +- **AGP Version**: [Current] -> Upgrade to 9.0. +- **Full Mode**: Not enabled. Remove `android.enableR8.fullMode=false` + from `gradle.properties`. + +## 2. Global disable rules + +*(Optional section for the report, omit if no relevant findings are present.)* + +- [Rule]: Disables R8 globally. **Action**: Remove. + +If there is -dontobfuscate, -dontoptimize or -dontshrink in the codebase, +mention in this section + +## 3. Optimization summary + +- **Optimization Score**: [X]% code is available for R8 optimizations +(e.g., inlining, merging) .[100-X]% of codebase can't be optimized by R8. +- **Shrinking Score**: [X]% of code will be optimized by R8 by removing +unused classes, fields and methods. [100-X]% of codebase contains redundant +classes, fields and methods that can't be removed by R8. +- **Obfuscation Score**: [X]% of the codebase is available for R8 to obfuscate. + +Increasing these score increases the codebase available to R8 for optimizations. + +## 4. Keep rules evaluation + +### [Rule Text] + +- **Keeps**: [X] items or [X] % of the codebase from optimization. Classes: [X], Fields: [X], Methods: [X] are prevented from optimization due to this keep rule +- **Kept items**: [Class1], [Class2] +- **Action**: **Remove** (Library bundles rules) OR **Refine** (Too broad, use [Surgical Rule]). + +## 5. Subsumed keep rules + +*(Optional section for the report, omit if no relevant findings are present.)* + +### [Redundant rules] + +- **Subsumed By**: [Broader Rule] +- **Action**: **Remove**. + +## 6. Historical analysis summary + +*(Only include this section if a previous report existed. Summarize the changes +in optimization scores here to track progress. For example:)* +The previous app had scores: Optimization (XX%), Obfuscation (XX%), +and Shrinking (XX%). +The current app has scores: Optimization (YY%), Obfuscation (YY%), +and Shrinking (YY%). +**Change**: Optimization improved by ZZ%, Obfuscation improved by ZZ%, +and Shrinking improved by ZZ%. \ No newline at end of file From 2d37f9be723f18c06d620e75ea746afb5c930d1c Mon Sep 17 00:00:00 2001 From: vinishavathwani Date: Mon, 18 May 2026 20:31:21 +0530 Subject: [PATCH 2/6] Minor clean ups --- performance/r8-analyzer/SKILL.md | 3 +-- performance/r8-analyzer/references/CONFIGURATION-ANALYZER.md | 5 ++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/performance/r8-analyzer/SKILL.md b/performance/r8-analyzer/SKILL.md index 65966fd..d79fadb 100644 --- a/performance/r8-analyzer/SKILL.md +++ b/performance/r8-analyzer/SKILL.md @@ -47,7 +47,7 @@ metadata: - **Manual evaluation** : Inspect `proguard-rules.pro`. - **Library check** : Compare rules against [references/REDUNDANT-RULES.md](references/REDUNDANT-RULES.md) .Suggest **Remove** for bundled rules. - **Custom rule check** : Use [references/KEEP-RULES-IMPACT-HIERARCHY.md](references/KEEP-RULES-IMPACT-HIERARCHY.md) and [references/REFLECTION-GUIDE.md](references/REFLECTION-GUIDE.md) to prioritize and evaluate. Suggest **Refine** for broad rules (e.g., package-wide). -- **Validation** : Suggest Macrobenchmark tests using [ui automator](references/android/training/testing/other-components/ui-automator.md) for any proposed changes. Proceed to Step 3. +- **Validation** : Suggest Macrobenchmark tests using [UI Automator](references/android/training/testing/other-components/ui-automator.md) for any proposed changes. Proceed to Step 3. ## Step 3. Report generation @@ -55,7 +55,6 @@ metadata: - **Input**: Extract metrics (Scores, Impacts, Example Classes) directly from generated file analysis.txt if using Path A, or from manual findings if using Path B. - - **Output** : Output ONLY the raw Markdown report in the chat. Do NOT output conversational filler (e.g., "Here is your report..."). diff --git a/performance/r8-analyzer/references/CONFIGURATION-ANALYZER.md b/performance/r8-analyzer/references/CONFIGURATION-ANALYZER.md index 6e30d37..6f1ca6f 100644 --- a/performance/r8-analyzer/references/CONFIGURATION-ANALYZER.md +++ b/performance/r8-analyzer/references/CONFIGURATION-ANALYZER.md @@ -1,4 +1,4 @@ -# CONFIGURATION ANALYZER DATA GENERATION +# Configuration Analyzer data generation On each step, keep the user informed of the progress by displaying the output. @@ -230,8 +230,7 @@ rm tmp/r8analysis/*.pb ### 10. Protobuf Python bindings -The following script `keep_radius_pb2.py` is required by the - conversion script in Step 5. +The following script `keep_radius_pb2.py` is required by the conversion script in Step 5. ```python from google.protobuf import descriptor as _descriptor From 1723ac2633e6727c9da4c37e31500058e46a3200 Mon Sep 17 00:00:00 2001 From: Vinisha Athwani <35296563+vinishavathwani@users.noreply.github.com> Date: Mon, 18 May 2026 20:34:25 +0530 Subject: [PATCH 3/6] Apply suggestion from @gemini-code-assist[bot] Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- performance/r8-analyzer/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/performance/r8-analyzer/SKILL.md b/performance/r8-analyzer/SKILL.md index d79fadb..361a243 100644 --- a/performance/r8-analyzer/SKILL.md +++ b/performance/r8-analyzer/SKILL.md @@ -45,7 +45,7 @@ metadata: *(Use ONLY if quantitative data generation is not possible)* - **Manual evaluation** : Inspect `proguard-rules.pro`. -- **Library check** : Compare rules against [references/REDUNDANT-RULES.md](references/REDUNDANT-RULES.md) .Suggest **Remove** for bundled rules. +- **Library check** : Compare rules against [references/REDUNDANT-RULES.md](references/REDUNDANT-RULES.md). Suggest **Remove** for bundled rules. - **Custom rule check** : Use [references/KEEP-RULES-IMPACT-HIERARCHY.md](references/KEEP-RULES-IMPACT-HIERARCHY.md) and [references/REFLECTION-GUIDE.md](references/REFLECTION-GUIDE.md) to prioritize and evaluate. Suggest **Refine** for broad rules (e.g., package-wide). - **Validation** : Suggest Macrobenchmark tests using [UI Automator](references/android/training/testing/other-components/ui-automator.md) for any proposed changes. Proceed to Step 3. From dfc3bcd5564f443d886b051ad01ecf5d9e632ba0 Mon Sep 17 00:00:00 2001 From: Vinisha Athwani <35296563+vinishavathwani@users.noreply.github.com> Date: Mon, 18 May 2026 20:35:06 +0530 Subject: [PATCH 4/6] Apply suggestion from @gemini-code-assist[bot] Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- performance/r8-analyzer/references/REPORT_FORMAT.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/performance/r8-analyzer/references/REPORT_FORMAT.md b/performance/r8-analyzer/references/REPORT_FORMAT.md index b8aaa9c..fd483fd 100644 --- a/performance/r8-analyzer/references/REPORT_FORMAT.md +++ b/performance/r8-analyzer/references/REPORT_FORMAT.md @@ -20,7 +20,7 @@ mention in this section ## 3. Optimization summary - **Optimization Score**: [X]% code is available for R8 optimizations -(e.g., inlining, merging) .[100-X]% of codebase can't be optimized by R8. +(e.g., inlining, merging). [100-X]% of codebase can't be optimized by R8. - **Shrinking Score**: [X]% of code will be optimized by R8 by removing unused classes, fields and methods. [100-X]% of codebase contains redundant classes, fields and methods that can't be removed by R8. From 8ab1279de2e0e7099315eb3a21814acf24228568 Mon Sep 17 00:00:00 2001 From: Vinisha Athwani <35296563+vinishavathwani@users.noreply.github.com> Date: Mon, 18 May 2026 20:35:19 +0530 Subject: [PATCH 5/6] Apply suggestion from @gemini-code-assist[bot] Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> --- performance/r8-analyzer/references/REPORT_FORMAT.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/performance/r8-analyzer/references/REPORT_FORMAT.md b/performance/r8-analyzer/references/REPORT_FORMAT.md index fd483fd..c98e939 100644 --- a/performance/r8-analyzer/references/REPORT_FORMAT.md +++ b/performance/r8-analyzer/references/REPORT_FORMAT.md @@ -26,7 +26,7 @@ unused classes, fields and methods. [100-X]% of codebase contains redundant classes, fields and methods that can't be removed by R8. - **Obfuscation Score**: [X]% of the codebase is available for R8 to obfuscate. -Increasing these score increases the codebase available to R8 for optimizations. +Increasing these scores increases the codebase available to R8 for optimizations. ## 4. Keep rules evaluation From 18b9010222b9f81eecf7d33d8514a8da166f0fb2 Mon Sep 17 00:00:00 2001 From: vinishavathwani Date: Mon, 18 May 2026 20:44:19 +0530 Subject: [PATCH 6/6] Update SKILL.md --- performance/r8-analyzer/SKILL.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/performance/r8-analyzer/SKILL.md b/performance/r8-analyzer/SKILL.md index 361a243..51dc623 100644 --- a/performance/r8-analyzer/SKILL.md +++ b/performance/r8-analyzer/SKILL.md @@ -46,7 +46,7 @@ metadata: - **Manual evaluation** : Inspect `proguard-rules.pro`. - **Library check** : Compare rules against [references/REDUNDANT-RULES.md](references/REDUNDANT-RULES.md). Suggest **Remove** for bundled rules. -- **Custom rule check** : Use [references/KEEP-RULES-IMPACT-HIERARCHY.md](references/KEEP-RULES-IMPACT-HIERARCHY.md) and [references/REFLECTION-GUIDE.md](references/REFLECTION-GUIDE.md) to prioritize and evaluate. Suggest **Refine** for broad rules (e.g., package-wide). +- **Custom rule check** : Use [references/KEEP-RULES-IMPACT-HIERARCHY.md](references/KEEP-RULES-IMPACT-HIERARCHY.md) and [references/REFLECTION-GUIDE.md](references/REFLECTION-GUIDE.md) to prioritize and evaluate. Suggest **Refine** for broad rules (for example, package-wide). - **Validation** : Suggest Macrobenchmark tests using [UI Automator](references/android/training/testing/other-components/ui-automator.md) for any proposed changes. Proceed to Step 3. ## Step 3. Report generation @@ -57,7 +57,7 @@ metadata: or from manual findings if using Path B. - **Output** : Output ONLY the raw Markdown report in the chat. - Do NOT output conversational filler (e.g., "Here is your report..."). + Do NOT output conversational filler (for example, "Here is your report..."). Do NOT provide recommendations, next steps, or any other text outside of the sections defined in [references/REPORT_FORMAT.md](references/REPORT_FORMAT.md) @@ -68,4 +68,4 @@ metadata: - **Strict output limit**: The final output MUST strictly be the Markdown report and nothing else. - **No code changes**: Research and suggest only; Do not modify files. - **No redundancy**: Do not explain R8 benefits or reference skill internal files in the report. -- **Focus**: Omit sections (e.g., Subsumed Rules, Configuration) if no issues or items are found. \ No newline at end of file +- **Focus**: Omit sections (for example, Subsumed Rules, Configuration) if no issues or items are found. \ No newline at end of file