我正在使用一些哈希,其中某些哈希的值是其他哈希的关键。
我需要多次使用key
来获取值的键,以便我可以使用它来访问另一个哈希中的内容。
我想知道这可能带来什么样的性能影响。在我的情况下,这些哈希的数量很少,而且内容很小,但我想在理论上知道。
我应该避免使用太多吗?与获取密钥的值相比,它的表现如何?
答案 0 :(得分: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 }
给他一个赞成票!
答案 1 :(得分: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对于过早优化是正确的,你不应该担心它。