Skip to content

Commit 0089ce9

Browse files
authored
Add macrobenchmarks (#5100)
* add macrobenchmarks * update okio comment
1 parent 547ec6c commit 0089ce9

File tree

18 files changed

+7721
-69
lines changed

18 files changed

+7721
-69
lines changed

benchmark/README.md

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,23 @@
33
This is a standalone Android Studio project to benchmark performance. While the root `apollo-kotlin` project can be
44
opened with IntelliJ, this one requires Android Studio.
55

6-
It's not a composite build so it's easy to swap the Apollo version and to workaround interop issues between AGP and multiplatform builds.
6+
It's not a composite build to workaround interop issues between AGP and multiplatform builds.
77
Use `publishAllPublicationsToPluginTestRepository` from `apollo-kotlin` to use the artifacts from the current version.
88

99
## Running the tests
1010

11-
You can run the tests from Android Studio by clicking the "run" icon in the gutter next to `class Benchmark`. This will
12-
print the results in the `Run` window of Android Studio
11+
You can run the tests from Android Studio by clicking the "run" icon in the gutter. This will
12+
print the results in the `Run` window of Android Studio.
13+
14+
For the command line, use:
15+
16+
```
17+
# macrobenchmarks
18+
./gradlew -p benchmark :macrobenchmark:connectedBenchmarkAndroidTest
19+
20+
# microbenchmarks
21+
./gradlew -p benchmark :microbenchmark:benchmarkReport
22+
```
1323

1424
## Inspiration
1525

benchmark/app/README.md

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,2 @@
1-
A small empty apk to make Firebase Test Labs happy because it requires an 'app' APK:
1+
A small app to monitor start performance and also to pass as an (unused) app apk to Firebase test labs for microbenchmarks.
22

3-
```
4-
gcloud --project apollo-kotlin firebase test android run --type=instrumentation
5-
--device model=Pixel3,locale=en,orientation=portrait --test=benchmark/build/outputs/apk/androidTest/release/benchmark-release-androidTest.apk
6-
--app benchmark/app/build/outputs/apk/release/app-release-unsigned.apk
7-
```

benchmark/app/build.gradle.kts

Lines changed: 75 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,22 @@
1-
apply(plugin = "com.android.application")
2-
apply(plugin = "org.jetbrains.kotlin.android")
1+
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
2+
import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
33

4-
configure<com.android.build.gradle.AppExtension> {
5-
namespace = "com.apollographql.apollo3.emptyapp"
4+
plugins {
5+
id("com.android.application")
6+
id("org.jetbrains.kotlin.android")
7+
id("com.apollographql.apollo3")
8+
}
9+
10+
android {
11+
namespace = "app_under_test"
612

7-
compileSdkVersion(libs.versions.android.sdkversion.compile.get().toInt())
13+
compileSdk = libs.versions.android.sdkversion.compilebenchmark.get().toInt()
814

915
defaultConfig {
10-
minSdk = libs.versions.android.sdkversion.min.get().toInt()
16+
minSdk = libs.versions.android.sdkversion.compose.min.get().toInt()
1117
targetSdk = libs.versions.android.sdkversion.target.get().toInt()
1218

1319
val debugSigningConfig = signingConfigs.getByName("debug").apply {
14-
// This is all public. This app is only an empty shell to make Firebase happy because it requires an 'app' APK.
1520
keyAlias = "key"
1621
keyPassword = "apollo"
1722
storeFile = file("keystore")
@@ -21,7 +26,70 @@ configure<com.android.build.gradle.AppExtension> {
2126
buildTypes {
2227
getByName("release") {
2328
signingConfig = debugSigningConfig
29+
isMinifyEnabled = true
30+
}
31+
create("benchmark") {
32+
initWith(getByName("release"))
33+
signingConfig = debugSigningConfig
34+
isMinifyEnabled = true
35+
isDebuggable = false
36+
applicationIdSuffix = ".benchmark"
37+
proguardFiles("rules.pro")
2438
}
2539
}
2640
}
41+
42+
@Suppress("UnstableApiUsage")
43+
buildFeatures {
44+
compose = true
45+
}
46+
47+
composeOptions {
48+
kotlinCompilerExtensionVersion = libs.versions.compose.compiler.get()
49+
}
50+
}
51+
52+
dependencies {
53+
implementation("com.apollographql.apollo3:apollo-runtime")
54+
implementation("com.apollographql.apollo3:apollo-normalized-cache")
55+
implementation(libs.compose.runtime)
56+
implementation(libs.compose.ui)
57+
implementation(libs.androidx.profileinstaller)
58+
implementation(libs.androidx.activity)
59+
}
60+
61+
tasks.withType<KotlinJvmCompile>().configureEach {
62+
compilerOptions {
63+
jvmTarget.set(JvmTarget.JVM_1_8)
64+
}
65+
}
66+
67+
val generateQueries: Provider<Task> = tasks.register("generateQueries") {
68+
inputs.file("src/main/graphql/api/operations.graphql")
69+
.withPropertyName("inputGraphQLFile")
70+
.withPathSensitivity(PathSensitivity.RELATIVE)
71+
outputs.dir(buildDir.resolve("generated/graphql/api"))
72+
.withPropertyName("outputDir")
73+
74+
doLast {
75+
val inputDocument = inputs.files.singleFile.readText()
76+
val outputDir = outputs.files.singleFile
77+
outputDir.deleteRecursively()
78+
outputDir.mkdirs()
79+
80+
repeat(10) {
81+
outputDir.resolve("operation$it.graphql").writeText(
82+
inputDocument.replace("#SuffixPlaceholder", it.toString())
83+
)
84+
}
85+
}
86+
}
87+
apollo {
88+
service("api") {
89+
packageName.set("com.apollographql.sample")
90+
//generateCompiledField.set(false)
91+
addTypename.set("always")
92+
srcDir(generateQueries)
93+
schemaFile.set(file("src/main/graphql/api/schema.graphqls"))
94+
}
2795
}

benchmark/app/rules.pro

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Obsfuscation must be disabled for the build variant that generates Baseline Profile, otherwise
2+
# wrong symbols would be generated. The generated Baseline Profile will be properly applied when generated
3+
# without obfuscation and your app is being obfuscated.
4+
-dontobfuscate
5+
6+
# Annotations referenced by androidx.benchmark and androidx.test
7+
-dontwarn androidx.core.os.BuildCompat$PrereleaseSdkCheck
8+
-dontwarn androidx.core.os.BuildCompat
9+
-dontwarn com.google.errorprone.annotations.CanIgnoreReturnValue
10+
-dontwarn com.google.errorprone.annotations.MustBeClosed
Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,20 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<manifest />
2+
<manifest xmlns:tools="http://schemas.android.com/tools"
3+
xmlns:android="http://schemas.android.com/apk/res/android">
4+
<uses-permission android:name="INTERNET" />
5+
<!-- Storage permissions required to run the macrobenchmark on my Pixel 3, not sure why -->
6+
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
7+
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
8+
<application >
9+
<profileable android:shell="true"
10+
tools:targetApi="q" />
11+
12+
<activity android:name=".MainActivity"
13+
android:exported="true">
14+
<intent-filter>
15+
<action android:name="android.intent.action.MAIN" />
16+
<category android:name="android.intent.category.LAUNCHER" />
17+
</intent-filter>
18+
</activity>
19+
</application>
20+
</manifest>
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
query GetResponse#SuffixPlaceholder
2+
{
3+
users
4+
{
5+
_id
6+
index
7+
guid
8+
is_active
9+
balance
10+
picture
11+
age
12+
eye_color
13+
name {
14+
first
15+
last
16+
}
17+
company
18+
email
19+
phone
20+
address
21+
about
22+
registered
23+
latitude
24+
longitude
25+
tags
26+
range
27+
friends {
28+
id
29+
name
30+
}
31+
images {
32+
id
33+
format
34+
url
35+
description
36+
}
37+
greeting
38+
favorite_fruit
39+
}
40+
status
41+
is_real_json
42+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
type Query {
2+
users(param: String): [User!]!
3+
status: String!
4+
is_real_json: Boolean!
5+
}
6+
7+
type User {
8+
_id: String!,
9+
index: Int!,
10+
guid: String!,
11+
is_active: Boolean!,
12+
balance: String!,
13+
picture: String!,
14+
age: Int!,
15+
name: Name!,
16+
company: String!,
17+
email: String!,
18+
address: String!,
19+
about: String!,
20+
registered: String!,
21+
latitude: Float!,
22+
longitude: Float!,
23+
tags: [String!]!,
24+
range: [Int!]!,
25+
friends: [Friend!]!,
26+
images: [Image!]!,
27+
greeting: String!,
28+
favorite_fruit: String!,
29+
eye_color: String!,
30+
phone: String!,
31+
}
32+
33+
type Name {
34+
first: String!,
35+
last: String!,
36+
}
37+
38+
type Friend {
39+
id: Int!,
40+
name: String!,
41+
}
42+
43+
type Image {
44+
id: String!,
45+
format: String!,
46+
url: String!,
47+
description: String!,
48+
}

0 commit comments

Comments
 (0)