6

JProfiler を使用して、理解できない Java コードのホット スポットを特定しました。JProfiler は、このメソッドに平均で 150μs (ウォームアップなしで 674μs) かかると説明しています。これには、子孫メソッドの呼び出しにかかる時間が含まれます。150μs はそれほど多くないように見えるかもしれませんが、このアプリケーションでは合計され (そして私のユーザーが経験しています)、これよりも複雑に見える他の方法と比較して、多くのように見えます。したがって、それは私にとって重要です。

private boolean assertReadAuthorizationForFields(Object entity, Object[] state,
        String[] propertyNames) {
    boolean changed = false;
    final List<Field> fields = FieldUtil.getAppropriatePropertyFields(entity, propertyNames);
    // average of 14 fields to iterate over
    for (final Field field : fields) {
        // manager.getAuthorization returns an enum type
        // manager is a field referencing another component
        if (manager.getAuthorization(READ, field).isDenied()) {
            FieldUtil.resetField(field.getName(), state, propertyNames);
            changed = true;
        }
    }
    return changed;
}

私自身、この方法をさまざまな方向に最小限に抑えましたが、あまり役に立ちません。JProfiler が報告する所要時間 (150μs) は、単にこのメソッドのコードに関するものであり、実行にかかる時間は含まれていないことを強調することはできませgetAuthorizationん。問題はこのコードにあり、その後の子孫メソッドの呼び出しではないように思われるため、文脈をあまり考慮せずにこのスニペットを投稿することから始めるのもそのためです。isDeniedresetField

たぶん、あなたは理由を議論することができます - もしあなたが私が幽霊を見ていると感じたら:) とにかく、あなたの時間をありがとう!

4

3 に答える 3

1

あなたを遅くする可能性のある候補の行動:

  • 主な影響: 明らかに反復。多くのフィールドがある場合... 平均で 14 と言いますが、これはかなり重要です。
  • 主な効果: ホットスポットのインライン化は、呼び出されたメソッドが時間に含まれることを意味します。これは、メソッド呼び出しがリフレクションを使用しているため、目立つ可能性があります。getAppropriatePropertyFields は、クラス フィールド定義メタデータを内省します。resetField はセッター メソッドを動的に呼び出します (おそらく Method.invoke()?? を使用)。どうしてもパフォーマンスが必要な場合は、HashSet (ElementClass->FieldMetadataAndMethodHandle のマッピング) を介してキャッシュを使用できます。これには、フィールド メタデータとセッター メソッドの MethodHandles を含めることができます (遅い method.invoke を使用する代わりに)。次に、アプリケーションの起動時に反映するだけで、JVM の高速な dynamicInvoke サポートを使用します。
  • マイナーな効果 - ただし、反復回数が乗算されます。状態名とプロパティ名の配列が非常に大きく、それらがプリミティブ フィールドを使用している場合、メソッドの呼び出し中にある程度のコピーが必要になります (メソッド パラメーターは実際には「値で渡す」)。プリミティブの参照渡し/コピー渡しを意味します)
于 2013-04-21T14:40:57.123 に答える
0

プロファイラーが常に正確なタイミングを提供するとは限らないため、自分でメソッドの時間を計ることをお勧めします。

このコードだけでマイクロベンチマークを作成し、少なくとも 2 秒間計測します。メソッド呼び出しの違いを調べるには、それらをコメントアウトし、それらが返す値をハードコーディングします。

于 2013-03-17T04:37:11.063 に答える
0

問題は、FieldUtil が Reflection を使用しており、使用しているフィールドをキャッシュしていないことだと思います。

于 2013-05-31T15:23:06.080 に答える