LoginSignup
2
0

More than 5 years have passed since last update.

【Java】正規表現で制御文字を除去したらめっぽう遅かった

Last updated at Posted at 2018-06-03

INDEX

  • 概要
  • 検証コード
  • 検証結果
  • まとめ
  • 追記(2018/06/05)
  • 追記のまとめ(2018/06/05)

概要

てなことで、String#replaceAllで制御文字を除去したらサーバ応答が結構遅くなったので、検証コードを書いてみたら確かに遅そうだと分かったよと言う話です。

検証コード

  • 次の様な処理をするコードを準備した(GitHubへ
    • ASCIIのみのテストデータの生成
    • String#replaceAllで制御文字を置換する
      • 1000回実施した時の時間を記録する
    • String#chatAtで制御文字を判別して新たに文字列を生成
      • 1000回実施した時の時間を記録する

コードの使い方

検証結果

  • 私のPC環境では大体replaceAllよりもcharAtの方が大体2倍速いという事になった。
試行回数 replaceAll charAt
1 11,170 5,377
2 11,337 5,437
3 11,203 5,418
4 11,114 5,489
5 11,294 5,527

※単位はms

まとめ

  • 正規表現は便利なんだけど、大量データを捌かないといけない場合等は、全部置換する実装ではなく、限定的に使うようにするなどの注意が必要だなーと思いました。1

追記(2018/06/05)

  • Pattern.compileで予めインスタンスを作ったらどうかというコメントがありましたので、追加検証しました。

検証コード

検証結果

  • ↑の検証では、横着してEclipse上から実施していたので今度はコンソール上で実施しました。
mahny@ALFA c:\Users\mahny\Desktop\speedcrazy
> java -cp .;speedcrazy.jar jp.gr.mahny_conf.replaceall_charat.GenerateTestData

mahny@ALFA c:\Users\mahny\Desktop\speedcrazy
> java -cp .;speedcrazy.jar jp.gr.mahny_conf.replaceall_charat.SpeedCrazyReplaceAll
合計時間 : 12006(ms), 平均時間 : 12(ms)

mahny@ALFA c:\Users\mahny\Desktop\speedcrazy
> java -cp .;speedcrazy.jar jp.gr.mahny_conf.replaceall_charat.SpeedCrazyPattern
合計時間 : 11023(ms), 平均時間 : 11(ms)

mahny@ALFA c:\Users\mahny\Desktop\speedcrazy
> java -cp .;speedcrazy.jar jp.gr.mahny_conf.replaceall_charat.SpeedCrazyCharAt
合計時間 : 5589(ms), 平均時間 : 5(ms)

mahny@ALFA c:\Users\mahny\Desktop\speedcrazy
> java -cp .;speedcrazy.jar jp.gr.mahny_conf.replaceall_charat.GenerateTestData

mahny@ALFA c:\Users\mahny\Desktop\speedcrazy
> java -cp .;speedcrazy.jar jp.gr.mahny_conf.replaceall_charat.SpeedCrazyReplaceAll
合計時間 : 11189(ms), 平均時間 : 11(ms)

mahny@ALFA c:\Users\mahny\Desktop\speedcrazy
> java -cp .;speedcrazy.jar jp.gr.mahny_conf.replaceall_charat.SpeedCrazyPattern
合計時間 : 10947(ms), 平均時間 : 10(ms)

mahny@ALFA c:\Users\mahny\Desktop\speedcrazy
> java -cp .;speedcrazy.jar jp.gr.mahny_conf.replaceall_charat.SpeedCrazyCharAt
合計時間 : 5573(ms), 平均時間 : 5(ms)

mahny@ALFA c:\Users\mahny\Desktop\speedcrazy
> java -cp .;speedcrazy.jar jp.gr.mahny_conf.replaceall_charat.GenerateTestData

mahny@ALFA c:\Users\mahny\Desktop\speedcrazy
> java -cp .;speedcrazy.jar jp.gr.mahny_conf.replaceall_charat.SpeedCrazyReplaceAll
合計時間 : 11038(ms), 平均時間 : 11(ms)

mahny@ALFA c:\Users\mahny\Desktop\speedcrazy
> java -cp .;speedcrazy.jar jp.gr.mahny_conf.replaceall_charat.SpeedCrazyPattern
合計時間 : 11152(ms), 平均時間 : 11(ms)

mahny@ALFA c:\Users\mahny\Desktop\speedcrazy
> java -cp .;speedcrazy.jar jp.gr.mahny_conf.replaceall_charat.SpeedCrazyCharAt
合計時間 : 5594(ms), 平均時間 : 5(ms)

mahny@ALFA c:\Users\mahny\Desktop\speedcrazy
> java -cp .;speedcrazy.jar jp.gr.mahny_conf.replaceall_charat.GenerateTestData

mahny@ALFA c:\Users\mahny\Desktop\speedcrazy
> java -cp .;speedcrazy.jar jp.gr.mahny_conf.replaceall_charat.SpeedCrazyReplaceAll
合計時間 : 11201(ms), 平均時間 : 11(ms)

mahny@ALFA c:\Users\mahny\Desktop\speedcrazy
> java -cp .;speedcrazy.jar jp.gr.mahny_conf.replaceall_charat.SpeedCrazyPattern
合計時間 : 10829(ms), 平均時間 : 10(ms)

mahny@ALFA c:\Users\mahny\Desktop\speedcrazy
> java -cp .;speedcrazy.jar jp.gr.mahny_conf.replaceall_charat.SpeedCrazyCharAt
合計時間 : 5593(ms), 平均時間 : 5(ms)

mahny@ALFA c:\Users\mahny\Desktop\speedcrazy
> java -cp .;speedcrazy.jar jp.gr.mahny_conf.replaceall_charat.GenerateTestData

mahny@ALFA c:\Users\mahny\Desktop\speedcrazy
> java -cp .;speedcrazy.jar jp.gr.mahny_conf.replaceall_charat.SpeedCrazyReplaceAll
合計時間 : 11164(ms), 平均時間 : 11(ms)

mahny@ALFA c:\Users\mahny\Desktop\speedcrazy
> java -cp .;speedcrazy.jar jp.gr.mahny_conf.replaceall_charat.SpeedCrazyPattern
合計時間 : 11049(ms), 平均時間 : 11(ms)

mahny@ALFA c:\Users\mahny\Desktop\speedcrazy
> java -cp .;speedcrazy.jar jp.gr.mahny_conf.replaceall_charat.SpeedCrazyCharAt
合計時間 : 5584(ms), 平均時間 : 5(ms)

mahny@ALFA c:\Users\mahny\Desktop\speedcrazy
>
試行回数 String#replaceAll Pattern#match String#charAt
1 12,006 11,023 5,589
2 11,189 10,497 5,573
3 11,038 11,152 5,594
4 11,201 10,829 5,593
5 11,164 11,049 5,584

※単位はms

うーむ、若干速くなっている…けど、思ったほど効果ないな…。コードの書き方が悪いのかな?

追記のまとめ(2018/06/05)

  • 単一のPatternインスタンス2を準備した場合で、String#replaceAllを使った時より約4%ほど改善
  • とはいえ、charAtを使える場面ではその方がいいし、正規表現の使いどころは気をつけようという考えは変わらず

  1. 実際に正規表現を使った実装をした時、検証APが処理しきれず無応答になってしまったので…コワイコワイ 

  2. Patternクラスのコードを見る限りPattern.compile(String)の引数によってはインスタンス生成に時間が掛かりそうな感じだったので、今回の様な単純な制御文字削除だけでなく複雑な正規表現を持ってきたらもっと差が付いたんじゃないかと思った。そこまで複雑ならcharAtなんて使えた物じゃないだろうし今度検証してみようかな。 

2
0
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0