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!(hash.invert)
{
    :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 回答