5

私がループの巣の奥深くにいる場合、これらのどれがより効率的であるか疑問に思います:

if (!isset($array[$key])) $array[$key] = $val;

また

$array[$key] = $val;

読み取り可能なコードに関する限り、2番目の形式の方がはるかに望ましいです。実際には、名前は長く、配列は多次元です。したがって、最初のフォームは、私のプログラムではかなりぎこちなく見えてしまいます。

しかし、2番目の形式の方が遅いのではないかと思います。コードはプログラムで最も頻繁に実行される関数の1つであるため、より高速な形式を使用したいと思います。

一般的に、このコードは同じ値の「$key」で何度も実行されます。したがって、ほとんどの場合、$ array [$ key]はすでに設定されており、isset()はFALSEを返します。

私が同一でないコードを同一であるかのように扱っていることを恐れる人々のために明確にするために:プログラムのこの部分に関する限り、$valは定数です。実行時まではわかりませんが、プログラムの早い段階で設定されており、ここでは変更されません。したがって、どちらの形式でも同じ結果が得られます。そして、これは$valで取得するのに最も便利な場所です。

4

9 に答える 9

10

実際に必要な配列の場合:array_key_exists($key, $array)の代わりにisset($array[$key]).

于 2008-10-03T20:49:58.540 に答える
3

isset() は通常の変数では非常に高速ですが、ここには配列があります。配列のハッシュ マップ アルゴリズムは高速ですが、何もしない場合よりも時間がかかります。

現在、最初の形式は、値をフェッチまたは設定せずにハッシュを検索するだけなので、設定されていない値よりも多くの値が設定されている場合に高速になる可能性があります。したがって、それが違いのポイントになる可能性があります。設定されているキーで「ヒット」が多い場合は最初のフォームを選択し、「ミス」が多い場合は 2 番目のフォームを選択します。

これら 2 つのコードは同一ではないことに注意してください。最初の形式は、すでに設定されているキーの値を設定しません。「上書き」を防ぎます。

于 2008-10-03T20:40:52.347 に答える
2

$array[$key]設定しようとする前に、設定された状況に遭遇する頻度を測定しましたか? これについて一般的なアドバイスをすることはできないと思います。実際にこれらのケースが多数ある場合、 isset チェックは配列上の不要なセットを回避することで時間を節約できる可能性があるためです。ただし、これがめったにない場合は、オーバーヘッドによって速度が低下する可能性があります…. 最良の方法は、実際のコードでベンチマークを実行することです。

ただし、両方のコードが異なる結果になる可能性があることに注意してください。組み合わせの $val が常に同じではない場合$array[$key]、前者のコードは常に最初の値に設定し$val$array[$key]後者のコードは常にその組み合わせの最後の値に設定します。

$val(あなたはそれを認識しており、については常に同じだと思いますが$array[$key]、立ち寄る読者の中にはそうでない人もいるかもしれません。)

于 2008-10-03T20:45:21.810 に答える
1

真である場合とそうでない場合がある比較のオーバーヘッドは、もっと時間がかかるように思われます。

両方の構成でスクリプトを実行すると、パフォーマンス時間はどうなりますか?

于 2008-10-03T20:18:13.393 に答える
1

配列をチェックする必要がありますが、設定しようとしているレベルは含まれません。

セットするなら

$anArray[ 'level1' ][ 'level2' ][ 'level3' ] = ...

level3 を設定する前に、level2 までのパスが実際に存在することを確認する必要があります。

$anArray[ 'level1' ][ 'level2' ]

そうしないと実際に子犬が殺されることはありませんが、特定の環境によってはイライラする可能性があります.

実際に設定しているインデックスを確認する必要はありません。インデックスを自動的に設定すると宣言されることを意味するためです。

これを行う簡単な方法があります。

<?php

function create_array_path( $path, & $inArray )
{
    if ( ! is_array( $inArray ) )
    {
        throw new Exception( 'The second argument is not an array!' );
    }
    $traversed = array();
    $current = &$inArray;

    foreach( $path as $subpath )
    {
        $traversed[] = $subpath;
        if ( ! is_array( $current ) )
        {
            $current = array();
        }
        if ( ! array_key_exists( $subpath, $current ) )
        {
            $current[ $subpath ] = '';
        }
        $current = &$current[ $subpath ];
    }
}


$myArray = array();

create_array_path( array( 'level1', 'level2', 'level3' ), $myArray );

print_r( $myArray );

?>

これは出力されます:

    Array
    (
        [level1] => Array
            (
                [level2] => Array
                    (
                        [level3] => 
                    )

            )

    )
于 2009-01-28T12:31:08.420 に答える
0

isset()への追加の関数呼び出しは、どの割り当てよりも多くのオーバーヘッドを持つことがほぼ保証されています。2番目の形式が速くなければ、私は非常に驚きます。

于 2008-10-03T20:22:30.153 に答える
0

キーがそこにあるかどうかを確認するために実際のチェックが必要ですか? 空の配列に代入するisset()と、ループが遅くなります。また、データ操作で 2 回目のパスを実行しない限り、isset チェックを行わないことを強くお勧めします。これは操作ではなく人口です。

于 2008-10-03T20:46:49.730 に答える
0

PHP のソース コードを見て違いを確認できます。これが後のバージョンの PHP で異なるかどうかは確認しませんでしたが、PHP3 では連想配列機能がphp3/php3_hash.cにあるようです。

関数 _php3_hash_exists では、次のことが行われます。

  • キーはハッシュされます
  • 正しいバケットが見つかりました
  • 正しいアイテムが見つかるかどうかにかかわらず、バケツが歩きました

関数 _php3_hash_add_or_update:

  • ハッシュされた
  • バケツが見つかりました
  • 歩いた、存在する場合はオーバーライドされた
    • 存在しない場合は、新しく追加されました

したがって、関数呼び出しが 1 つしかなく、このハッシュとバケット検索のビジネスが 1 回しか行われないため、設定するだけの方が高速に見えます。

于 2008-10-06T17:53:21.123 に答える
0

私はPHPの初心者ですが、両方を組み合わせて三項演算子を使用できます

$array[$key] = !isset($array[$key]) ? $val : $array[$key];

それはそれと一緒に行く1つの方法です。

于 2008-10-03T20:53:45.693 に答える