Skip to content

Instantly share code, notes, and snippets.

@soeminhet
Created March 22, 2025 08:26
Show Gist options
  • Save soeminhet/51b0345f1c10249010959fc54cb136ff to your computer and use it in GitHub Desktop.
Save soeminhet/51b0345f1c10249010959fc54cb136ff to your computer and use it in GitHub Desktop.
import androidx.benchmark.junit4.BenchmarkRule
import androidx.benchmark.junit4.measureRepeated
import androidx.test.ext.junit.runners.AndroidJUnit4
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
/**
* Benchmark, which will execute on an Android device.
*
* The body of [BenchmarkRule.measureRepeated] is measured in a loop, and Studio will
* output the result. Modify your code to see how it affects performance.
*/
@Serializable
data class User(val id: Int, val name: String)
private val userJson = """
{
"id": 1,
"name": "Jack"
}
""".trimIndent()
private val userWithExtraJson = """
{
"id": 1,
"name": "Jack",
"extraField": "Android Developer",
"anotherUnknown": 12345
}
""".trimIndent()
@Serializable
data class LargeUser(
val id: Int,
val name: String,
val email: String,
val age: Int,
val country: String,
val city: String,
val phone: String,
val occupation: String,
val company: String,
val experience: Int,
val skills: List<String>,
val hobby: String,
val married: Boolean,
val height: Double,
val weight: Double,
val bloodType: String,
val favoriteColor: String,
val petName: String,
val vehicle: String,
val language: String,
val education: String,
val university: String,
val graduationYear: Int,
val github: String,
val linkedin: String,
val twitter: String,
val website: String,
val blog: String,
val notes: String
)
val largeUserJson = """
{
"id": 1,
"name": "Jack",
"email": "[email protected]",
"age": 30,
"country": "USA",
"city": "New York",
"phone": "+1234567890",
"occupation": "Software Engineer",
"company": "ExampleCorp",
"experience": 5,
"skills": ["Kotlin", "Java", "Compose", "Coroutines"],
"hobby": "Reading",
"married": true,
"height": 180.0,
"weight": 75.0,
"bloodType": "A",
"favoriteColor": "Green",
"petName": "Buddy",
"vehicle": "Motorbike",
"language": "English",
"education": "Master's Degree",
"university": "Example University",
"graduationYear": 2020,
"github": "https://github.com/jackdev",
"linkedin": "https://linkedin.com/in/jackdev",
"twitter": "@jackdev",
"website": "https://jack.dev",
"blog": "https://blog.jack.dev",
"notes": "This is a sample user for testing."
}
""".trimIndent()
val largeUserWithExtraJson = """
{
"id": 1,
"name": "Jack",
"email": "[email protected]",
"age": 30,
"country": "USA",
"city": "New York",
"phone": "+1234567890",
"occupation": "Software Engineer",
"company": "ExampleCorp",
"experience": 5,
"skills": ["Kotlin", "Java", "Compose", "Coroutines"],
"hobby": "Reading",
"married": true,
"height": 180.0,
"weight": 75.0,
"bloodType": "A",
"favoriteColor": "Green",
"petName": "Buddy",
"vehicle": "Motorbike",
"language": "English",
"education": "Master's Degree",
"university": "Example University",
"graduationYear": 2020,
"github": "https://github.com/jackdev",
"linkedin": "https://linkedin.com/in/jackdev",
"twitter": "@jackdev",
"website": "https://jack.dev",
"blog": "https://blog.jack.dev",
"notes": "This is a sample user for testing.",
"extra1": "extraValue1",
"extra2": 42,
"extra3": 3.14,
"extra4": false,
"extra5": null
}
""".trimIndent()
private fun buildLargeJson(): String {
val builder = StringBuilder()
builder.append("{")
builder.append("\"id\": 1,")
builder.append("\"name\": \"Jack\",")
for (i in 1..10_000) {
builder.append("\"unknownField$i\": \"value$i\",")
}
builder.setLength(builder.length - 1)
builder.append("}")
return builder.toString()
}
@RunWith(AndroidJUnit4::class)
class ExampleBenchmark {
@get:Rule
val benchmarkRule = BenchmarkRule()
val userWithLargeExtraJson = buildLargeJson()
@Test
fun small_user_with_ignore_unknown_keys() {
decodeMeasure<User>(
userJson,
true
)
}
@Test
fun small_user_without_ignore_unknown_keys() {
decodeMeasure<User>(
userJson,
false
)
}
@Test
fun small_user_with_extra_properties_with_ignore_unknown_keys() {
decodeMeasure<User>(
userWithExtraJson,
true
)
}
@Test
fun small_user_with_extra_properties_without_ignore_unknown_keys() {
decodeMeasure<User>(
userWithExtraJson,
false
)
}
@Test
fun large_user_with_ignore_unknown_keys() {
decodeMeasure<LargeUser>(
largeUserJson,
true
)
}
@Test
fun large_user_without_ignore_unknown_keys() {
decodeMeasure<LargeUser>(
largeUserJson,
false
)
}
@Test
fun large_user_with_extra_properties_with_ignore_unknown_keys() {
decodeMeasure<LargeUser>(
largeUserWithExtraJson,
true
)
}
@Test
fun large_user_with_extra_properties_without_ignore_unknown_keys() {
decodeMeasure<LargeUser>(
largeUserWithExtraJson,
false
)
}
@Test
fun small_user_with_large_extra_properties_with_ignore_unknown_keys() {
decodeMeasure<User>(
userWithLargeExtraJson,
true
)
}
@Test
fun small_user_with_large_extra_properties_without_ignore_unknown_keys() {
decodeMeasure<User>(
userWithLargeExtraJson,
false
)
}
private inline fun <reified T> decodeMeasure(value: String, ignore: Boolean) {
val json = Json { ignoreUnknownKeys = ignore }
benchmarkRule.measureRepeated {
runCatching {
json.decodeFromString<T>(value)
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment