# R8 Optimization: Method Outlining

DevFeed: [R8 Optimization: Method Outlining](<https://devfeed.tech/articles/r8-optimization-method-outlining-20960.md>)

Original publisher: [Read original article](<https://jakewharton.com/r8-optimization-method-outlining/>)

Published: 2019-04-11T00:00:00Z

Content type: article

Language: en

Sources: [Jake Wharton](<https://devfeed.tech/sources/jake-wharton.md>)

Topics: [R8](<https://devfeed.tech/topics/r8.md>), [Optimization](<https://devfeed.tech/topics/optimization.md>), [Android](<https://devfeed.tech/topics/android.md>), [Code](<https://devfeed.tech/topics/code.md>), [JSON](<https://devfeed.tech/topics/json.md>)

Tags: [android](<https://devfeed.tech/tags/android.md>), [code](<https://devfeed.tech/tags/code.md>), [examples](<https://devfeed.tech/tags/examples.md>), [exception](<https://devfeed.tech/tags/exception.md>), [java](<https://devfeed.tech/tags/java.md>), [json](<https://devfeed.tech/tags/json.md>), [optimization](<https://devfeed.tech/tags/optimization.md>), [r8](<https://devfeed.tech/tags/r8.md>), [reduce](<https://devfeed.tech/tags/reduce.md>)

## AI overview

This article explains how R8 optimization can make duplicated generated code smaller than a generated helper method in an Android APK. Using Moshi-style JSON parsing as the example, it discusses repeated exceptions and string-building logic generated for non-null properties, and why R8 method outlining and related optimizations affect the final bytecode size.

## Source excerpt

Note: This post is part of a series on D8 and R8, Android's new dexer and optimizer, respectively. For an intro to D8 read "Android's Java 8 support". For an intro to R8 read "R8 Optimization: Staticization". I recently wrote about the economics of generated code which talked about performing optimizations to generated code that aren't worthwhile in manually-written code. While the examples in that post were motivated by changes to code generators that I had worked on in the past, it also resulted in some new changes being made. One change proposed to Moshi, a JSON serializer, replaced its generated strings with StringBuilder to de-duplicate the constant parts. Each non-null property in your JSON model generates an exception to ensure non-null values are read from the JSON. name = stringAdapter.fromJson(reader) ?: throw JsonDataException( - "Non-null value 'name' was null at ${reader.path}") + StringBuilder("Non-null value '").append("name") + .append("' was null at ").append(reader.path).toString()) A second exception is generated when that non-null property lacks a default value and no value was present in the JSON. return Person( name = name ?: throw JsonDataException( - "Required property 'name' missing at ${reader.path}"), + StringBuilder("Required property '").append("name") + .append("' missing at ").append(reader.path).toString()), These two diffs are the result of applying the advice from that post. Each of these exceptions are generated for every property in the type. This means if you have a type with 10 properties you get 20 exceptions generated (assuming they're non-null and don't have default values). This winds up creating a lot of StringBuilder bytecode! One way to reduce this bytecode bloat is to generate a private method which takes four arguments (prefix, name, suffix, path) and returns the final string. This was proposed as part of the change to Moshi. We ultimately duplicated the code instead of generating a method because it ends up optimizing