我正在使用几个哈希,其中一些哈希的值是其他哈希的键。
我需要使用key
几次来获取一个值的键,以便我可以使用它来访问另一个哈希中的某些内容。
我想知道这可能会对性能产生什么样的影响。在我的情况下,这些哈希的数量很少,内容也很小,但我想从理论上知道。
我应该避免使用太多吗?与获取键的值相比,它的性能如何?
我正在使用几个哈希,其中一些哈希的值是其他哈希的键。
我需要使用key
几次来获取一个值的键,以便我可以使用它来访问另一个哈希中的某些内容。
我想知道这可能会对性能产生什么样的影响。在我的情况下,这些哈希的数量很少,内容也很小,但我想从理论上知道。
我应该避免使用太多吗?与获取键的值相比,它的性能如何?
这样想:你偶尔会做一个额外的步骤来获得价值。每当您使用条件测试并在计算中添加几个步骤时,都会发生这种情况。
很明显,这会带来一些开销,但此时担心它是过早的优化。您可以通过使用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 }
给他一个赞成票!
在 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 关于过早优化是正确的,您不必担心。