Javaのパフォーマンスチューニング - 文字列と数値の構造

  私の新しい本、Javaのパフォーマンスチューニング(仮称)からこのブログは、章2.1および2.2,2.10からの抜粋も、私の著書「春ブーツ2本質」を購入することを歓迎
  
  文字列の構築2.1を
  
  不変であるJavaで文字列を、構築または傍受するかどうか、常に新しい文字列を取得します。ストリング見えるように構成され、ソース
  
  []民間最終char値を、
  
  公共の文字列(文字列オリジナル){
  
  this.value = original.value;
  
  this.hash = original.hash;
  
  }
  
  直接参照を割り当てることにより、元の文字列の値の配列char配列の両方の文字列を共有新しい文字列値、ので、この工法に最速の構成を有しています。Javaで文字列オブジェクトは不変になるように設計されています。プログラムは、文字列オブジェクトの参照を取得することを意図された後、この文字列を心配していない、他の場所で変更不変の意味のスレッドセーフな、不変オブジェクトのスレッドセーフの第三章と説明されています。
  
  より頻繁に建設列文字列は、この場合、性能が非常に低い場合、文字列を構築するバイト[]を使用して文字列の配列、またはいくつかのフレームをデシリアライズすることにより構成されています。以下のchar []配列は、新たなソース文字列構築によって
  
  パブリック文字列(char値[]){
  
  this.value = Arrays.copyOf(値、value.length);
  
  }
  
  Arrays.copyOf新しいアレイを再コピー、次のように
  
  静的チャーパブリック[] copyOf(CHAR []オリジナル、newLengthのINT){
  
  文字[] =新しい新しいチャーコピー【newLength];
  
  System.arraycopyの(オリジナル、0、コピー、0、
  
  Math.min(original.lengthに、newLength)) ;
  
  コピーを返す;
  
  }
  
  あなたは、実際には文字列の配列によって構築新しい文字列配列を作成していることがわかります。、またはchar配列への直接参照は、あなたが外部のchar型の配列を変更した場合ので、その後、新しい文字列が変更された場合ではありません。
  
  ; [] = CS新しい新しいcharは[] { 'A'、 'B'} char型
  
  文字列新しい新しいSTR =(CS);
  
  '!' CS [0] =
  
  コードの最後の行上、変性CSアレイではなく、意志影響STR。strが実際に構成新しい文字列配列であるため、
  
  新しい文字列char配列のコンストラクタで、この方法は、このような列として、このメソッドを呼び出します、ほぼすべての文字列のAPIを見て、私たちの後ろに、最長の新しい文字列を作成し使用しています連結および他の方法。符号列新しい列構成によって検証、およびCHAR列アレイの性能比較で構成されているように
  
  、文字列str =「こんにちは、文字列」;
  
  char型[] = str.toCharArrayの文字();
  
  [@Benchmark](HTTPS: //my.oschina。
  

  
  新しい新しいStringリターン(STR);
  
  }
  
  [@Benchmark](https://my.oschina.net/u/3268003)
  
  パブリック文字列stringByCharArray(www.yuchenghd.com){
  
  ;(文字)新規新しい文字列を返す
  
  }
  
  / NSに出力オペアンプの出力は、両方のは時間がかかり、より多くの時間がかかるが、配列が特に長い場合は特に、それがあるとき、ナノ秒のコールの数は、あなたが最初の文字列またはchar構造で見ることができますたびに使用
  
  ベンチマークスコアモード単位
  
  ciccNewStringTest.stringは4.235 nsのをavgtを/ OP
  
  ciccNewStringTest.stringByCharArrayは/ OP 11.704ナノ秒をavgt
  
  バイト配列に文字列を、非常に一般的な状況で、特に今配布され、マイクロ人気のサービス、クライアントのシーケンスの文字列を構築することで、バイト、とにあなたを送りますサーバは、サーバは、バイト列で構成、デシリアライズされ
  
  たバイト列構成性能試験用いた試験下記
  
  ;(「UTF-8」)[]バイトをBS =「こんにちは、文字列」.getBytes
  
  @Benchmark [ (https://my.oschina.net/u/3268003)
  
  パブリック文字列stringByByteArray(www.yuchengyule.comは){例外をスロー
  
  新しい新しいStringリターン(BS、「UTF-8」);
  
  }
  
  テスト結果は非常に長い時間がかかるためにストリング構成する場合は特に、バイト文字列があまりにも時間がかかるように構成見ることができる
  
  ベンチマークモードスコア単位
  
  ciccNewStringTest.stringは4.649 NSをavgt / OP
  
  ciccNewStringTest.www.yifayule2d.com stringByByteArrayは、OP / 82.166 NSをavgt
  
  ciccNewStringTest.stringByCharArrayは12.138 NS / OP avgt
  
  バイトアレイストリング構造により、トランスコード処理に主に関連し、内部コールトランスコードStringCoding.decode
  
  this.value = StringCoding.decode(たcharsetName、バイト、オフセット、長さ);
  
  たcharsetNameが文字セットを表し、バイトオフセット、バイト配列であり、代表長さバイト配列
  
  実際のトランスコーディングは、sun.nio.cs.UTF_8の責任文字セットサブクラスでありますデコード方法は、深いこのカテゴリにあれば、あなたはあなたが見ることがわかります、バイトのトランスコーディングを担当し、その下の氷は、それが部品を最適化されていない、非常にCPU集中型コンピューティング・トランスコーディング作業で、氷山の一角です。
  
  プロセスでのシステムのパフォーマンスの最適化I時間は、データセットのバイト列によって発見され、より前方の位置で常に構成されたCPUの消費量で、システム性能のトランスコーディングは、サービスコードの価値は100行を消費します。したがって、我々は転送されるように慎重に設計フィールドを必要とし、分散するシステムを設計し、文字列を使用しないようにしてみてください。ビジネス状態のタイプを示すために、例えば使用することができる長い時間が整数によって表すことができます。シリアル化されたオブジェクトが必要
  
  OrderResponseパブリッククラス{
  
  //注文日付、フォーマット「YYYY-MM-DD」
  
  プライベート文字列CREATEDATE;
  
  //注文ステータス、「www.dafengyuLept.comは」正常示し
  
  プライベート文字列ステータス;
  
  }
  
  以上に変更することができますうまくシリアライズとデシリアライズの負担を軽減するために、定義されました。
  
  OrderResponseクラス{公共
  
  //受注日
  
  プライベートロングCREATEDATE;
  
  //注文状況、0は正常を示し
  
  プライベートint型のステータスを;
  
  }
  
  マイクロサービス、シリアライズとデシリアライズ転送オブジェクトには、第IV章の章で改めて説明しますオブジェクトシリアライゼーション
  
  2.2文字列連結
  
  JDKが自動的に自動的に文字列連結のStringBuilder、次のコードに変換され、+記号を使用して作製:
  
  列A =「こんにちは」;
  
  列B =「世界」
  
  の文字列STR = A + B。
  
  仮想チャンスは、次のコードのコンパイル
  
  文字列str =新しいStringBuilderのを(www.chaoyuepint.com) .append(a)の.append(b)の.toString();
  
  あなたは、テストとコードのかもしれないJMHセクションを実行する場合、パフォーマンスは、実際には同じであるの使用理由+の両方の上になり、仮想マシン・コード・セグメントのいくつかの最適化を行うために、一般的なオペレーティング・ストリングに接続され、仮想-XXの使用:+ OptimizeStringConcatオープン文字列連結最適化、(デフォルトではオープン)。上記のコード断片と類似しているんが、次のコードは、仮想マシンは、この文字列の連結モードを認識できない場合は、パフォーマンスがたくさんドロップします
  
  。新しい新しいSB =()のStringBuilderのStringBuilderを
  
  sb.append(A);
  
  sb.append( B);
  
  StringConcatTestクラスを実行して、次のように
  
  、文字列A = "ユーザーUから、u.nameをu.id SELECT"
  
  の文字列= B "を= u.id WHERE?";
  
  [@Benchmark](HTTPS://my.oschina .NET / U / 3268003)
  
  パブリック文字列連結(){
  
  文字列C = A + B、
  
  Cを返す;
  
  }
  
  [@Benchmark](https://my.oschina.net/u/3268003)
  
  パブリック文字列concatbyOptimizeBuilder(www.seocelve .COM){
  
  Cは、StringBuilderの新しい新しいString()アペンド(A).append(B).toString();. =
  
  リターンCを;
  
  }
  
  @Benchmark
  
  パブリックストリングconcatbyBuilder(){
  
  //最適化しない
  
  のStringBuilder StringBuilderの新しい新しいSB =を();
  
  sb.append (A);
  
  sb.append(B);
  
  (www.xingtuyLgw.com)sb.toStringを返す;
  
  }
  
  以下の結果は、役割が最適化された仮想マシンの再生例示で
  
  ベンチマークモードスコアユニット
  
  ciccStringConcatTest.concatは25.747 NS / OP avgt
  
  ciccStringConcatTest.concatbyBuilderを90.548 NS avgt / OP
  
  ciccStringConcatTest.concatbyOptimizeBuilderは21.904 NS / OPはavgt
  
  JVMを最適化していないので、concatbyBuilderが最も遅いです見ることができ
  
  、仮想マシンのJITの最適化を参照して、JVMの最適化することを、ここで、我々は第8章JITの最適化で説明します
  
  読者は、最適化されたかどうかを見て、自分自身に+ B + Cこの文字列連結のパフォーマンスを確認することができます
  
  、主な機能がAbstractStringBuilder継承されたStringBufferと類似のStringBuilderが同期キーワード使用して、このような追記方式としてスレッドセーフな方法を提供し、ある
  
  @Override
  
  パブリック同期StringBufferの追加(文字列strの){
  
  //他のコードを無視
  
  (WWW super.appendをSTR .huichengtxgw.com)、
  
  これを返す;
  
  }
  
  何スレッド同期文字列の連結に関連しないほとんどすべてのシーンを、StringBufferのはほとんど使用されないので、スプライシングのストリング使用のStringBufferの例として
  
  @Benchmark
  
  公共concatbyBuffer列(){
  
  たStringBuffer StringBufferの新しい新しい= SB();
  
  sb.append(A);
  
  sb.append(B);
  
  (sb.toStringを返す);
  
  }
  
  として出力
  
  ベンチマークモードスコアユニット
  
  ciccStringConcatTest.concatbyBufferは111.417 NSをavgt / OP
  
  ciccStringConcatTest.concatbyBuilderは/ 94.758 NSをavgtオペアンプ
  
  あなたは、パフォーマンススプライシング性能はに比べて悪いわけではないのStringBufferのStringBuilderで、ロックの除去だけでなく、状況を分析オープンJITエスケープである「解析を逃れる」仮想マシンのおかげで見ることができる、オブジェクトを排除することができますロックを使用して定義synchronzied。
  
  + EliminateLocks、第8章JITの最適化の詳細を参照して:DoEscapeAnalysisロック+と-XXを排除:分析-XXエスケープ
  
  ロックの例としては解除され、内部的に使用されるオブジェクトOBJの方法を、このように同期排除
  
  {ボイドのfoo()を
  
  //オブジェクトの作成
  
  オブジェクトOBJ =新しい新しいオブジェクト();
  
  同期(OBJ){
  
  doSomethingの();
  
  }
  
  }
  
  、ロックが、JIT最適化に依存し、排除するために、エスケープ分析を開くべきではなく、すべてのコードが最適化されることを保証することはできませんロックがプログラマとしてC2ステージJITの除去を最適化することであるため、関係のないスレッドの治安情勢は、StringBuilderのを使用する必要があります。
  
  JDK内のデジタル革命の文字型、作業の多くは、文字列への単純なint型は、あなたがコードの少なくとも50行を完了する必要があるためのStringBuilderに縫い合わせ、他の種類の、特にデジタルタイプを使用して、パフォーマンスが大幅に低減されます。これがあります。第一章では、我々は見てきたし、ここでは詳細に説明されていません。あなたは、文字列、スプライシング番号を連結するためのStringBuilderを使用すると、あなたは、このような文字列かどうか、を考える必要があります。
  
  2.10のBigDecimalは、
  
  我々は、すべての問題の計算の精度の浮動小数点変数の損失が生じることになるときことを知っています。以下のコード
  
  System.out.println(0.05 + 0.01)
  
  のSystem.out.println(1.0から0.42);
  
  出力:0.5800000000000001 0.060000000000000005は
  
  Javaで行う浮動小数点演算ときに見ることができ、精度の損失の問題が発生します。もしそうなら、私たちは商品価格を行なう際に、問題があるでしょう。私たちの手の0.06元になる可能性が、0.05元と0.01元商品を購入することはできません。その2 0.060000000000000005の合計は、上記に示したように。これは、並行電力供給業者のウェブサイトアップの量は、問題が膨大になる場合は特に、間違いなく非常に深刻な問題です。引き起こす可能性が注文した、または和解の問題が発生することができません。
  
  通常、我々は、彼らが最高の効率である、単位に分割される口座の残高を表すために長く使用できるかどうか、この問題を解決する方法の両方を持っています。ない場合は、あなただけのような問題を解決するために、BigDecimalクラスを使用することができます。
  
  新しい新しい= BigDecimalをBigDecimalを( "0.05");
  
  BigDecimalの新しい新B = BigDecimalを( "0.01");
  
  BigDecimalのRET = a.add(B)
  
  のSystem.out.println(ret.toString());
  
  文字列で構成さ0.05の精度は、それ自体が失われているため、新規のBigDecimal(0.05)は、BigDecimalのうちの構造を作ることも精度を紛失した場合のBigDecimalは、精度を確保するために、失われることはありません。
  
  BigDecimalの精度を保証するために、いくつかの衝撃性能を計算する必要があります、以下の計算は、パフォーマンスの比較を示した要素と長い点、で表される平衡試験、あるBigDecimalを
  
  新しい新しい= BigDecimalをBigDecimalを( "0.05");
  
  BigDecimalの新しい新B = BigDecimalを( "0.01");
  
  ロング5 = C;
  
  ロングD = 1;
  
  @Benchmark
  
  @CompilerControl(CompilerControl.Mode.DONT_INLINE)
  
  パブリックロングaddByLong(){
  
  リターン(C + D);
  
  }
  
  @Benchmark
  
  @CompilerControl(CompilerControl.Mode.DONT_INLINE)
  
  パブリックaddByBigDecimalのBigDecimal(){
  
  ; a.add戻る(B)
  
  }
  
  私のマシンのラインに、上記のコードを正確にJMHによって計算することができます、以下のように試験結果は
  
  ベンチマークモードスコアユニット
  
  ciccBigDecimalTest.addByBigDecimalは8.373 NS / OP avgt
  
  / OP 2.984 NS avgt ciccBigDecimalTest.addByLongを
  
  決済は精度を必要とするのであれば、プロジェクトで、二重使用していない、BigDecmalの使用を検討し、また、長い間、考慮にシリアライズとデシリアライズを取って、分散またはマイクロサービスシナリオ、良好なパフォーマンスで、長精度計算を完了するために使用することができますすべてのフレームワーク配列にも識別することができ
  
  、コンテンツ参照https://www.whonyLpt.com .COM / P / c81edc59546c

おすすめ

転載: www.cnblogs.com/qwangxiao/p/11112884.html