graphql-java / graphql-java/graphql-java
1% possible memory and cpu improvements
まだ誰も着手していません。
- 主要言語
- Java
- スター
- 6.2k
- フォーク
- 1.1k
- 平均マージ
- 22分
- マージ済み PR(30日)
- 14
説明
graphql-java is a mature and optimised library. So its increasingly difficult to find performance improvements that really stand out.
This leads us to the 1% club where we need to do a bunch of work to get a small 1% gain
This issue tries to capture investigations of these 1%'ers and hence be a list of possible micro improvements
Profiler investigations - memory
Running ComplexQueryPeformance as load and using JProfiler
The biggest objects are as follows
"graphql.execution.ExecutionStrategyParameters", 4% of memory
"graphql.execution.ExecutionStrategyParameters$Builder", 4% of memory use
"graphql.execution.ExecutionStepInfo" 2%
"graphql.execution.ExecutionStepInfo$Builder", 2%
"graphql.execution.NonNullableFieldValidator", 2%
"graphql.execution.FetchedValue", 2%
I have PRS that try to reduce all these - eg either remove the builder usage for "transforms" (ExecutionStrategyParameters and ExecutionStepInfo)
or avoid re-allocating per field (NonNullableFieldValidator and FetchedValue)
https://github.com/graphql-java/graphql-java/pull/3924
https://github.com/graphql-java/graphql-java/pull/3929
https://github.com/graphql-java/graphql-java/pull/3934
https://github.com/graphql-java/graphql-java/pull/3935
The builder ones reduce by memory per type by half right - because we no longer create a builder to actually create a ExecutionStepInfo say
interesting future things to look into
-
"graphql.util.IntraThreadMemoizedSupplier", 4%
** why so heavy - do we strictly need it -
"graphql.schema.FieldCoordinates" 2%
** can we avoid this some how - flyweights? -
"graphql.schema.PropertyFetchingImpl$CacheKey", 2%
** can we avoid this some how - flyweights? -
"com.google.common.collect.SingletonImmutableList", 2%
** why so high?? Are we wrapping something for no reason -
"graphql.schema.DataFetcherFactoryEnvironment", 2%
** "graphql.schema.DataFetcherFactoryEnvironment$Builder" 2%
** this can go I think
asserts cost cpu and memory
eg :
this.executionStepInfo = assertNotNull(executionStepInfo, () -> "executionStepInfo is null");
These asserts are great for code reasons - but they cost something to run
Can we use the jspecify annotations here and remove these because static analysis is giving us the safety ?
cpu hot spots to look into
-
1.6% - 1,256 ms - 1,372,469 hot spot inv. graphql.schema.GraphQLCodeRegistry.getDataFetcherImpl
-
1.5% - 1,190 ms - 7,119,736 hot spot inv. graphql.schema.GraphQLTypeUtil.unwrapNonNull
-
1.5% - 1,209 ms - 7,088,722 hot spot inv. graphql.execution.ExecutionStepInfo.getUnwrappedNonNullType
-
1.3% - 1,010 ms - 12,160,902 hot spot inv. graphql.Assert.assertNotNull(java.lang.Object, java.util.function.Supplier)
-
1.0% - 786 ms - 1,485,657 hot spot inv. graphql.execution.ExecutionStrategy.unboxPossibleDataFetcherResult
This is an interesting one - its called on DataFetch BUT its also called in completeValueForList
meaning can a DF returns a DataFetcherResult that itself is a list of DataFetcherResult of values. Is this even remotely sensible?? Can we kill it in lists the name of 1% ??
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
プロファイラの調査結果と既存のPR 3924、3929、3934、3935から始め、次にComplexQueryPeformanceを実行してベースラインを確立します。一覧にあるメモリまたはCPUホットスポットを1つ選び、その関連するエントリポイントを追跡します。完了とするには、ベースラインに対して検証された測定可能な改善が必要です。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- graphql, java
- 領域
- backend-api-design, performance
- issue の種類
- リファクタリング
- 難易度
- 5/5
- 見積もり時間
- 1週間以上
- 活発さ
- 停滞
- 明瞭さ
- 説明が足りない
- 初心者へのやさしさ
- 25/100