2

int 配列に格納された 2 つのパターンを比較する App Engine Java の関数があります。

以下はコードです:

public static int patternMatch(int [] pattern1, int [] pattern2, int range) {

    int max = range * pattern1.length;

    int match = (pattern1.length - pattern2.length) * range;

    for(int i = 0; i < pattern2.length; i++) {
        match += Math.abs(pattern1[i] - pattern2[i]);
    }

    return (max - match) * 100 / max;
}

以下にリストされているように、開発サーバーとアプリ エンジンへの展開の間のこの関数のパフォーマンスに関して、非常に奇妙な問題に直面しています。

  1. この関数は、最適な一致を見つける目的でループ内で呼び出されます。
  2. 多くの反復があるため、単一の反復のパフォーマンスが重要です。
  3. このコードにロジックがなく、整数を直接返す場合、コード全体が完了するまでに平均で 100 ミリ秒かかります。
  4. 上記のコードは、200 ~ 600 ミリ秒かかります。
  5. 開発サーバーで、「int match = (pattern1.length - pattern2.length) * range;」を置き換えると、「int match = Math.abs(pattern1.length - pattern2.length) * range;」によって、なぜかパフォーマンスが向上し、かかる時間が 200 ~ 300 ミリ秒に短縮されました。展開サーバーへの影響はありません。
  6. 「Math.abs」を削除すると、パフォーマンスが向上し、平均が 150 ミリ秒になります。
  7. Math.abs をビット演算に置き換えて絶対値を導出してみました。開発サーバーで最大 160 ミリ秒の大幅なパフォーマンスの向上が見られます。展開サーバーでは、状況が悪化し、〜 700 ミリ秒になります。

ここで知りたいことは次のとおりです。 1. 開発サーバー (Windows 7/Eclipse/JDK6) と展開サーバーは、パフォーマンスの調整に関して、なぜ、どのように異なる動作をするのですか? 2. より良いアルゴリズムはありますか?

困惑しています。どんな助けでも感謝します。

4

1 に答える 1

1

これは良い質問です。私が考えることができる 1 つの問題は、一度展開すると実行するハードウェアに保証がないことです。別の実行では、より高速/低速のサーバーで実行できます。よくテストすると思いますが、さまざまなコード サンプルを同じリクエスト ハンドラ内で実行して、それらが同じインスタンスで実行されていることがわかるようにします。

于 2012-11-15T16:23:38.600 に答える