4

いくつかのハッシュの値が他のハッシュのキーであるいくつかのハッシュを使用しています。

key別のハッシュの何かにアクセスするために使用できるように、値のキーを取得するために数回使用する必要があります。

これがパフォーマンスにどのような影響を与える可能性があるのか​​ 疑問に思っていました。私の状況では、これらのハッシュは数が少なく、内容は小さいですが、理論的に知りたいです。

これは使いすぎないようにすべきでしょうか?キーの値を取得する場合と比較して、どのように機能しますか?

4

2 に答える 2

2

このように考えてください: 値を取得するために追加の手順を実行する場合があります。これは、条件付きテストを使用し、計算にいくつかのステップを追加するたびに発生することです。

それに伴うオーバーヘッドが少しあることは明らかですが、この時点でそれを心配するのは時期尚早の最適化です。Benchmarkクラスを使用して、ハッシュ キーを取得する別の方法と通常の方法をテストすることで、違いを感じることができます。

かなりの違いを確認するには、数百万回のループを実行する必要があると思います。


@fontanusが言及した逆マッピングを作成する方法は次のとおりです。

hash = {a:1, b:2}
hash.merge!(Hash[hash.values.zip(hash.keys)])

結果は次のとおりです。

{
    :a => 1,
    :b => 2,
     1 => :a,
     2 => :b
}

ハッシュを配列に強制し、それをフラット化し、逆にしてからハッシュに戻すことによっても実行できますが、これは上記よりも直感的ではありません。YMMV。

hash.merge!(Hash[*hash.to_a.flatten.reverse])

@steenslag を思い出したHash.invert。何かがあることは知っていましたが、メソッド名を思い出せませんでした:

>> hash.merge!(ハッシュ.反転)
{
    :a => 1,
    :b => 2,
     1 => :a,
     2 => :b
}

彼に賛成票を投じてください!

于 2013-05-02T13:21:02.510 に答える
1

ruby 1.9.3 と 2.0.0 での検索は O(n) 操作です。

static VALUE
rb_hash_key(VALUE hash, VALUE value)
{
    VALUE args[2];

    args[0] = value;
    args[1] = Qnil;

    rb_hash_foreach(hash, key_i, (VALUE)args);

    return args[1];
}

の実装rb_hash_foreach:

void
rb_hash_foreach(VALUE hash, int (*func)(ANYARGS), VALUE farg)
{
    struct hash_foreach_arg arg; 

    if (!RHASH(hash)->ntbl)
        return;
    RHASH_ITER_LEV(hash)++;
    arg.hash = hash;
    arg.func = (rb_foreach_func *)func;
    arg.arg  = farg;
    rb_ensure(hash_foreach_call, (VALUE)&arg, hash_foreach_ensure, hash);
}

それでも、あなたのハッシュは小さいです。@theTinMan は時期尚早の最適化について正しいので、心配する必要はありません。

于 2013-05-02T12:55:05.477 に答える