铸造成本?

1 c# caching casting

我在Dictionary<string, Dictionary<string, string>>被调用的id2key_value中有一个由哈希(ID)映射的键/值对.您可以将此视为用行表示类似数据库的表的一种方法.

我添加了一些辅助函数来通过执行转换来简化一些基本数据类型的使用,比如

public int GetInt(string id, string key)
{
    int value = 0;
    bool success = int.TryParse(map[id][key], out value);

    if (success)
        return value;
    else
        throw new InvalidOperationException(
            "Trying to obtain a non-integer value with GetInt().");
}
Run Code Online (Sandbox Code Playgroud)

好吧,当我想出一个"cast-cache"的想法时,我觉得我很聪明,它基本上保存了已经解析过的对象,所以我可以跳过对int,bool,DateTime等字符串的解析,以及只需将它们从缓存中转换为适当的数据类型.喜欢,

public int GetInt(string id, string key)
{
    if (cast_cache.ContainsKey(id) && cast_cache[id].ContainsKey(key))
        return (int) cast_cache[id][key];

    int value = 0;
    bool success = int.TryParse(map[id][key], out value);

    if (success)
    {
        this.AddToCache(id, key, value);

        return value;
    }
    else
        throw new InvalidOperationException(
            "Trying to obtain a non-integer value with GetInt().");
}
Run Code Online (Sandbox Code Playgroud)

"cast-cache"很简单Dictionary<string, Dictionary<string, object>>.

所以,我做了一些性能测试,在地图上添加了10000个整数.然后我做了一百万随机检索,有没有"cast-caching".

没有缓存需要495(ms),缓存需要490(ms).我还使用DateTime进行了测试,差异更显着,但比我预期的要少(〜750(ms)非缓存vs~500(ms)缓存).

不是(显然)理解演员的原理,这个操作的成本是多少以及为什么表演如此接近于从字符串"反序列化"的表演?

And*_*are 11

由于您没有触及对象本身(您只是更改指向该对象的引用),因此大多数人似乎都认为编译速度要快得多.

您应该避免强制转换的主要原因之一是,当您进行转换时,您避免使用类型安全性并将潜在的执行时错误引入应用程序.我很少会考虑将其作为一个性能问题.

作为旁注,我将确保您在缓存中测试引用类型和值类型,以确保您不会因任何值类型的装箱和取消装箱而导致性能下降.

拳击的性能损失来自这样的事实:将值类型转换为对象确实涉及的不仅仅是更改引用,因为必须将值类型复制到堆中.此外,使用盒装值类型将取消打包引用类型,然后再将这些值从堆复制到堆栈.