0

処理する必要のあるリストがあります。アイテムは有効または無効になっています。ユーザーは、無効になっているアイテムを表示するかどうかを選択できます。

ですから、それcond2はアイテムに依存しますが、そうcond1ではありません。これが私が陥ったジレンマです:私は使うべきですかcond1 && !cond2、それとも!(!cond1 || cond2)?またはcond2、ループの前に(無効なアイテムを表示する)を確認する必要がありますか? また、ブール変数であり、「短絡」(遅延評価?)を使用すると、cond2cond1に置く必要があるかどうかも考えました(遅延評価?)。cond2

私の主な関心事はスピードでした。ループ内に多くのアイテムがある場合、これは重要な変更になる可能性があります。

これは、オプションを示すコードです。

// First Option
for (String item : items) {
    doSomethingFirst(item);
    if (isDisabled(item) && !showDisabled) {
        continue;
    }
    doSomethingElse(item);
}

// Second Option
for (String item : items) {
    doSomethingFirst(item);
    if (!(!isDisabled(item) || showDisabled)) {
        continue;
    }
    doSomethingElse(item);
}

// Third Option
if (showDisabled) {
    for (String item : items) {
        doSomethingFirst(item);
        doSomethingElse(item);
    }
} else {
    for (String item : items) {
        doSomethingFirst(item);
        if (isDisabled(item)) {
            continue;
        }
        doSomethingElse(item);
    }
}

それで、順序isDisabled(item)と重要性はありshowDisabledますか?ループの前に物事をチェックする必要がありますか?それともコンパイラはそれを最適化しますか?(私は疑う...)

PS実際の値を確認するためにどのように測定するかわかりません。関連がある場合は、実行してください。

ありがとう。

4

5 に答える 5

3

Javaでは、式は左から右に評価されます。&&最初の条件が偽の場合、2番目の条件||は実行されません。最初の条件が真の場合、2番目の条件は実行されません。

ですから、あなたの場合、そもそもより速く解決できる条件を置くようにしてくださいshowDisabled

3番目の例では、ブール値を1回だけチェックするので見栄えが良くなりますが、パフォーマンスは実際には変わらないと思います。ブール値の比較は実際にはコストがかかりません。あなたはおそらくあなたのコードの他の部分で行うより良い改善があるでしょう。(そして読みやすい面では、それは私のお気に入りではありません-かなり長いです)

ケースのパフォーマンスを測定する場合は、たとえばプロファイラーを使用します。

または、コードを追加します。

long start=System.currentTimeMillis();
//code to analyse
long timeSpent = System.currentTimeMillis()-start

関連性を持たせるために、コードをループに入れる必要があります。そして、Javaがいくつかのループの後にパフォーマンスを向上させることにおそらく気付くでしょう;)。

于 2012-05-26T09:24:23.497 に答える
2

読みやすさに関して、もう1つの良い方法は、関数と変数に正の状態で名前を付けることです。二重否定を読むのは難しいです。どちらを読みたいですか?

enabled

または

!disabled

ネガティブな形で物事に名前を付けることは理にかなっていますが、いくつかのケースがあります。たとえば、ファイルの終わりなどの終了条件にそれらを使用する場合。 while(!feof(fp))

しかし、ほとんどの場合、標準は物事にポジティブな形で名前を付けることであるはずなので、コードを読むことによる摩擦は少なくなります。

コードがポジティブな形でどのように見えるかを見てみましょう。

// First Option
for (String item : items) {
    doSomethingFirst(item);

    // if (isDisabled(item) && !showDisabled) {

    if (!isEnabled(item) && showEnabled) {
        continue;
    }
    doSomethingElse(item);
}

そのコードの読みやすさは確かに向上しました。

そして、以下も読みやすくなりますが、二重のネガを避けることができます。コードを読み取ることは、実際にはそれを読み取るだけであり、あまり理解しすぎません。私はかつて、コードを書くときは読むのもとても楽しいはずだと示唆する記事を読んだことがあります。彼は、コードを読むことは推理小説を読むようなものであってはならないと言いました。二重否定コードを読むことは、推理小説を読んで解読するようなものです。

// Second Option
for (String item : items) {
    doSomethingFirst(item);

    // if (!(!isDisabled(item) || showDisabled)) {

    // You can now avoid double negatives
    if (!( isEnabled(item) || !showEnabled )) {
        continue;
    }
    doSomethingElse(item);
}

実際、以下は単なる二重否定ではなく、三重否定です。

if (!(!isDisabled(item)

  1. 無効になっています
  2. !無効になっています
  3. !(!無効になっています

そのコードの目的を解読するには、2パスの読み取り、または3パスの読み取りが必要です。

于 2012-05-26T10:11:20.807 に答える
1

オプション1を選択し、スイッチを逆にします

isDisabled(item) && !showDisabled

!showDisabled && isDisabled(item)

isDisabled(...)あなたが言うのと同じくらい遅い場合は、最初に速いケースをテストする方が良いです。他のオプションと比較すると、これは最も明確で読みやすいものです。

  • 私たちはすべてのアイテムに対して何かが行われています
  • 一部のテストを検証する項目はスキップします
  • 他のすべてのアイテムに対して何かを行います。

より明確にすることは難しいでしょう。そして、3番目のオプションは明らかに醜いです。

于 2012-05-26T09:33:21.183 に答える
1

これらのタイプの質問と同様に、これを測定して、これ自体がボトルネックであるかどうかを判断する必要があります。もしそうなら、私は代替案を測定します。上記のシナリオでは、特にリストエントリを使用してはるかに重い作業を行う可能性があるため、代替案にほとんど違いがないのではないかと思います(それらを表示するか、データベースまたはファイルに書き込むか)。

これを測定する最も簡単な方法は、かなりのリストを生成し、処理、処理、および実行したミリ秒(または秒)の前に時間を記録することです(たとえば、System.currentTimeMillis()を介して)。

于 2012-05-26T09:20:31.177 に答える
1

cond1 &&!cond2または!(!cond1 || cond2)を使用する必要がありますか?または、ループの前にcond2(無効なアイテムを表示)を確認する必要がありますか?

あなたの考えを最もよく表現するもの、つまりより読みやすいものは何でも。

私の主な関心事はスピードでした。

書き込み速度?リファクタリング速度?コンパイル速度?開発スピードは?速度を読んで理解しますか?デバッグ速度?実行速度は?

一度に全部持つことはできません。言語なし。

于 2012-05-26T09:32:46.517 に答える