あなたが本当にパフォーマンスの世話をした場合、あなたはO(n × m)
時間の複雑さを避けるために試してみてくださいもう一方の文字ごとに1つの文字列を反復処理します。したがって、最初に効率的な(O(1)
)ルックアップをサポートするデータ構造を取得するために1つの文字列を繰り返し、次にこれを利用して繰り返します。文字列が十分に大きい場合
BitSet encountered = new BitSet();
test.chars().forEach(encountered::set);
int index = IntStream.range(0, other.length())
.filter(ix->encountered.get(other.charAt(ix)))
.findFirst().orElse(-1);
、このソリューションのO(n + m)
時間の複雑さがはるかに短い実行時間に変わります。小文字の場合は、とにかく無関係です。
あなたは本当に、文字列は(非常に低いです)、並列処理の恩恵を受けるのに十分な大きさである、あなたは小さなadaptionsと、並行して両方の操作を行うことができると思う場合は、次の
BitSet encountered = CharBuffer.wrap(test).chars().parallel()
.collect(BitSet::new, BitSet::set, BitSet::or);
int index = IntStream.range(0, other.length()).parallel()
.filter(ix -> encountered.get(other.charAt(ix)))
.findFirst().orElse(-1);
最初の操作が使用していますやや複雑なパラレル互換のcollect
があり、それはストリーム作成のためにそれほど明白でない変更を含んでいます。
問題はbug report JDK-8071477に記載されています。簡単に言えば、String.chars()
によって返されたストリームは分割能力が低いため、並列パフォーマンスが悪いです。上記のコードは、の文字列をラップしています。その文字列のchars()
メソッドは、同じセマンティクスを持ちながらも優れた並列パフォーマンスを持つ別の実装を返します。この回避策は、Java 9では時代遅れになっているはずです。を使用すると、良好な並列処理のストリームを作成することができます。 2番目の操作はすでにそのように動作します。
しかし、この特定のタスクでは、並行処理を有効にするのに十分な大きさの文字列に遭遇することはほとんどありません。
しかし、 'e'はインデックス '1'にあり、' t'も 'other'にありますので、' 0'を返します。 – Zircon
そして、並列ストリームを使用したパフォーマンスヒットのどれがここで紹介されるのだろうかと思います。言い換えれば、なぜ並列? – GhostCat
@ GhostCat、私は、各文字を並行してチェックすることで、最初の文字列がチェックされているものの複雑さになると考えています。それは出発点を持つことの問題であり、一度私はこれを適用できるより大きいテキストに達する。 – relisher