ほとんどの開発者は、パフォーマンスの最適化は複雑であり、多くの経験と知識が必要であると当然のことと考えています。まあ、これは完全に間違っているとは言えません。最適なパフォーマンスのためにアプリケーションを最適化することは簡単な作業ではありません。ただし、これは、この知識がなければ何もできないという意味ではありません。パフォーマンスの良いアプリケーションを作成するのに役立つ11の簡単なヒントとベストプラクティスがあります。
提案のほとんどはJava向けです。しかし、言語に依存しないいくつかの提案があり、すべてのアプリケーションとプログラミング言語に適用できます。 Java専用のパフォーマンスチューニング手法について議論する前に、一般的なヒントを見てみましょう。
1.必要であることがわかるまで最適化しないでください
これはおそらく最も重要なパフォーマンスチューニングのヒントの1つです。一般的なベストプラクティスに従い、ユースケースを効率的に実装しようとする必要があります。ただし、これは、必要であると証明する前に、標準ライブラリを交換したり、複雑な最適化を構築する必要があるという意味ではありません。
ほとんどの場合、時期尚早の最適化には多くの時間がかかるだけでなく、コードの読み取りと維持が困難になります。さらに悪いことに、これらの最適化は通常、最適化に多くの時間を費やしているのはアプリケーションの非批判的な部分であるため、利点はもたらされません。
それで、あなたは何かを最適化する必要があることをどのように証明しますか?
まず、アプリケーションコードがどれだけ速いか、たとえば、すべてのAPI呼び出しの最大応答時間を指定するか、特定の時間範囲でインポートするレコードの数を指定する必要があります。これを完了したら、アプリケーションのどの部分が遅すぎて改善できないかを測定できます。次に、2番目のトリックを見てみましょう。
2。アナライザーを使用して、実際のボトルネックを見つけます
最初の提案に従い、アプリケーションの一部が改善が必要であると判断した後、どこから始めればよいですか?
2つの方法で問題を解決できます。
あなたのコードをチェックして、疑わしいように見える部分から始めたり、問題があると感じるかもしれません。
または、アナライザーを使用して、コードの各部分の動作とパフォーマンスに関する詳細情報を取得します。
私が常に2番目の方法に従うべきかを説明する必要がないことを願っています。
パーサーベースのアプローチにより、コードのパフォーマンスへの影響をよりよく理解し、最も重要な部分に集中できるようにすることは明らかです。パーサーを使用した場合、コードのどの部分がパフォーマンスの問題を抱えているかを調べることに驚いたことを覚えておく必要があります。正直に言うと、私の最初の推測は私を何度も間違った方向に導きました。
3.アプリケーション全体にパフォーマンステストスイートを作成する
これは、生産のパフォーマンスの改善を展開した後にしばしば発生する多くの予期しない問題を回避するのに役立つ別の普遍的なヒントです。アプリケーション全体をテストするパフォーマンステストスイートを常に定義し、パフォーマンスの改善の前後に実行する必要があります。
これらの追加のテスト実行は、変更された機能とパフォーマンスの副作用を特定し、適切な更新以外の害が生じないことを確認します。これは、データベースやキャッシュなど、アプリケーションのいくつかの異なる部分で使用されるコンポーネントで作業する場合に特に重要です。
4.最初に最大のボトルネックを扱ってください
テストスイートを作成し、アナライザーを使用してアプリケーションを分析した後、パフォーマンスを改善するために対処する必要があるさまざまな問題をリストできます。これは素晴らしいことですが、それでもどこから始めるべきかという問題にまだ答えていません。クイック作用ソリューションに集中するか、最も重要な質問から始めることができます。
最初の結果をすばやく表示できるため、クイック作用スキームは最初は魅力的です。しかし、時には、他のチームメンバーや経営陣に、パフォーマンス分析は価値があることを納得させる必要があるかもしれません。現時点では効果がないからです。
しかし、全体として、最初に最も重要なパフォーマンスの問題に対処することをお勧めします。これにより、パフォーマンスの最大の改善が提供され、パフォーマンス要件を満たすためにこれらの問題のいくつかを解決する必要がなくなりました。
一般的なパフォーマンスチューニングのヒントはここで終了します。 Java固有のヒントを詳しく見てみましょう。
5. StringBuilderを使用して、プログラムで文字列を接続します
Javaの文字列を接続するには、さまざまなオプションがあります。たとえば、Simple +または + =、StringBufferまたはStringBuilderを使用できます。
では、どの方法を選択する必要がありますか?
答えは、文字列を接続するコードによって異なります。プログラムで新しいコンテンツをプログラムで追加している場合、たとえばforループで、stringbuilderを使用する必要があります。使いやすく、StringBufferよりも優れたパフォーマンスを提供します。ただし、StringBufferと比較して、StringBuilderはスレッドセーフではなく、すべてのユースケースに適していない場合があることを忘れないでください。
新しいStringBuilderをインスタンス化し、付録メソッドを呼び出して、文字列に新しいパーツを追加するだけです。すべての部品を追加したら、toString()メソッドを呼び出して接続された文字列を取得できます。
次のコードスニペットには、簡単な例が表示されます。各反復中、このループはiを文字列に変換し、スペースとともにStringBuilder SBに追加します。したがって、最後に、このコードは「これはログファイルに「test0 1 2 3 4 5 6 7 8 9」と記述されます。
stringbuilder sb = new StringBuilder( "これはテストです"); for(int i = 0; i <10; i ++){sb.append(i); sb.append( "");} log.info(sb.toString());コードスニペットでわかるように、文字列の最初の要素をコンストラクターに提供できます。これにより、提供された文字列と16の追加文字容量を含む新しいStringBuilderが作成されます。 StringBuilderにキャラクターを追加すると、JVMはStringBuilderのサイズを動的に増加させます。
文字列に含まれる文字の数が既にわかっている場合は、その数値を異なるコンストラクターに提供して、定義容量を持つStringBuilderをインスタンス化できます。これにより、容量の動的な拡大を必要としないため、効率がさらに向上します。
6. +を使用して、ステートメントで文字列を連結します
Javaで最初のアプリケーションを実装するとき、誰かがあなたが文字列に接続するために +を使用してはならないと言ったかもしれません。アプリケーションロジックで文字列を連結している場合、これは正しいです。文字列は不変であり、各文字列の連結の結果は新しい文字列オブジェクトに保存されます。これには追加のメモリが必要であり、特にループ内の複数の文字列を連結する場合、アプリケーションを遅くします。
これらの場合、ヒント5に従い、StringBuilderを使用する必要があります。
ただし、文字列を複数の行に分割してコードの読みやすさを向上させる場合、それは異なります。
クエリQ = em.createquery( "Select A.Id、A.FirstName、A.LastName"
+「著者Aから」
+「ここでa.id =:id」);
これらの場合、Simple +を使用して文字列を連結する必要があります。 Javaコンパイラはこれを最適化し、コンパイル時に接続を実行します。したがって、実行時には、コードは1文字列のみを使用し、接続は必要ありません。
7.可能な限りプリミティブを使用します
オーバーヘッドを回避し、アプリケーションのパフォーマンスを改善するもう1つの簡単で迅速な方法は、ラッパークラスの代わりに基本タイプを使用することです。したがって、整数の代わりにINTとダブルの代わりにダブルを使用することをお勧めします。これにより、JVMはヒープではなくスタックに値を保存して、メモリの消費を減らし、より効率的な処理を行うことができます。
8. BigintegerとBigDecimalを避けるようにしてください
データ型について議論しているので、BigintegerとBigDecimalを簡単に見てみましょう。特に、後者はその精度で人気があります。しかし、価格があります。
BigintegerとBigDecimalは、単純な長いまたはダブルよりも多くのメモリを必要とし、すべての計算を大幅に遅くします。したがって、余分な精度が必要な場合、または数字が長距離を超える場合は、それを行う前によく考えるのが最善です。これはおそらく、特に数学的アルゴリズムを実装する場合、パフォーマンスの問題を解決するために変更する必要がある唯一の方法です。
9.最初に現在のログレベルを確認します
この提案は明らかなはずですが、残念ながら、多くのプログラマーはコードを書くときにほとんどそれを無視しています。デバッグメッセージを作成する前に、最初に現在のログレベルを常に確認する必要があります。それ以外の場合は、後で無視されるログメッセージ文字列を作成する場合があります。
ここに2つの否定的な例があります。
// thislog.debug( "user [" + username + "]と呼ばれる[" + i + "]")
どちらの場合も、ログフレームワークがログメッセージを使用するかどうかを知らずに、ログメッセージを作成するために必要なすべての手順を実行します。したがって、デバッグメッセージを作成する前に、現在のログレベルを確認するのが最善です。
// do thisif(log.isdebugenabled()){log.debug( "user [" + username + "]と呼ばれる[" + i + "]");}10。string.replaceの代わりにapache commons stringutils.replaceを使用します
一般的に言えば、string.replaceメソッドは正常に機能し、特にJava 9を使用する場合は非常に効率的です。ただし、アプリケーションが多くの交換操作を必要とし、最新のJavaバージョンに更新されていない場合は、より高速で効率的な代替品を見つける必要があります。
Apache Commons LangのStringutils.replaceメソッドへの別の答えがあります。 Lukas Ederが最近のブログ投稿で説明したように、Stringutils.replaceメソッドはJava 8のString.replaceメソッドよりもはるかに優れています。
そして、それは小さな変更のみを必要とします。つまり、Apache Commons LangプロジェクトのMaven依存関係をアプリケーションpom.xmlに追加し、すべての呼び出しをString.utils.Replaceメソッドにstring.replaceメソッドに置き換えます。
// thistest.replace( "test"、 "simple test"); // thisstringutils.replace(test、 "test"、 "simple test");
11.データベース接続などの高価なリソースをキャッシュします
キャッシュは、高価なコードスニペットまたは一般的なコードスニペットの繰り返しの実行を避けるための一般的なソリューションです。一般的なアイデアは簡単です。新しいリソースを繰り返し作成するよりも、これらのリソースを再利用する方が安価です。
典型的な例は、キャッシュプールのデータベース接続です。新しい接続には、既存の接続を再利用すると回避できます。
また、Java言語自体に他の例を見つけることができます。たとえば、整数クラスの値は-128〜127の間で値をキャッシュします。新しい整数を作成するのはそれほど高価ではないと言うかもしれませんが、それがよく使用されるため、最も一般的に使用される値をキャッシュすることはパフォーマンスの利点をもたらすことができます。
ただし、キャッシュを検討する場合は、キャッシュの実装もオーバーヘッドが発生する可能性があることを忘れないでください。再利用可能なリソースを保存するために余分なメモリを使用する必要があるため、リソースをアクセスできるようにキャッシュを管理し、時代遅れのリソースを削除する必要がある場合があります。
したがって、リソースのキャッシュを開始する前に、キャッシュの実装が価値があることを確認してください。つまり、それらを十分に使用する必要があります。
要約します
ご覧のとおり、アプリケーションのパフォーマンスを改善するためにあまり作業が必要ではありません。この記事の提案のほとんどは、それらをコードに適用するためにほんの少しの努力を必要とします。
しかし、最も重要なことは、プログラミング言語とは関係のないトリックです。
アナライザーを使用して、必要であることがわかる前に、実際のボトルネックを見つけることを最適化しないでください。最初に最大のボトルネックを扱います。
上記は、この記事で共有されているすべてのコンテンツが、非常にシンプルで理解しやすいJavaパフォーマンスチューニング技術に関するものです。私はそれが誰にでも役立つことを願っています。興味のある友達は引き続きこのサイトを参照できます:
Javaは、WeChat Public Platform WeChat Momentsの機能を共有するための詳細なコードを実装しています
Javaネイティブシリアル化とKryoのシリアル化のパフォーマンスインスタンスの比較分析
Javaプログラミングサブクラスが親クラスの静的方法を書き換えることができるかどうかの調査
欠点がある場合は、それを指摘するためにメッセージを残してください。このサイトへのご支援をありがとうございました!