Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 铸造成本?_C#_Caching_Casting - Fatal编程技术网

C# 铸造成本?

C# 铸造成本?,c#,caching,casting,C#,Caching,Casting,我在字典中有一个通过散列(ID)映射的键/值对,称为id2key\u值。您可以将其视为用行表示类似数据库的表的一种方法 我添加了一些助手函数,通过执行强制转换来简化一些基本数据类型的使用,如 public int GetInt(string id, string key) { int value = 0; bool success = int.TryParse(map[id][key], out value); if (success) return v

我在
字典
中有一个通过散列(ID)映射的键/值对,称为id2key\u值。您可以将其视为用行表示类似数据库的表的一种方法

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

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().");
}

嗯,当我想到一个“强制缓存”的想法时,我觉得我很聪明,它基本上保存已经解析过的对象,所以我可以跳过对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().");
}
“强制转换缓存”只是
字典

因此,我在地图上添加了10000个整数,进行了一些性能测试。然后我做了一百万次随机检索,有没有“强制缓存”

不使用缓存时需要495(毫秒),使用缓存时需要490(毫秒)。我还使用DateTime进行了一次测试,差异更大,但比我预期的要小(约750(ms)非缓存对约500(ms)缓存)


(显然)不了解强制转换的原理,该操作的成本有多高,以及为什么性能与从字符串“反序列化”的性能如此接近?

强制转换的速度比大多数人想象的要快得多,因为您没有触及对象本身(您只是更改指向该对象的引用)

您应该避免强制转换的一个主要原因是,当您强制转换时,您避开了类型安全性,并在应用程序中引入了潜在的执行时间错误。我很少考虑铸件是一个性能问题。 作为补充说明,我将确保在缓存中测试引用类型和值类型,以确保不会因为装箱和取消装箱任何值类型而导致性能损失


装箱的性能损失来自这样一个事实:将值类型强制转换到对象并不涉及更改引用,因为值类型必须复制到堆中。此外,使用装箱值类型将取消装箱引用类型,然后将这些值从堆中再次复制到堆栈中。

由于您没有触及对象本身(您只是更改指向该对象的引用),因此强制转换比大多数人想象的快得多

您应该避免强制转换的一个主要原因是,当您强制转换时,您避开了类型安全性,并在应用程序中引入了潜在的执行时间错误。我很少考虑铸件是一个性能问题。 作为补充说明,我将确保在缓存中测试引用类型和值类型,以确保不会因为装箱和取消装箱任何值类型而导致性能损失


装箱的性能损失来自这样一个事实:将值类型强制转换到对象并不涉及更改引用,因为值类型必须复制到堆中。此外,使用装箱值类型将取消装箱引用类型,然后将这些值从堆中再次复制到堆栈中。

由于时间和空间之间的关系,您的示例运行得更快。如果继续缓存每个哈希类型,程序需要多少内存?

由于时间和空间之间的关系,您的示例运行得更快。如果继续缓存每种哈希类型,程序需要多少内存?

等等,您在代码中称为“强制转换”的不是强制转换

如果您正在这样做:

bool success = int.TryParse(map[id][key], out value);
这是一种转换,而不是演员阵容。演员阵容将是:

value = (int) map[id][key];

在这种情况下会失败,因为对象实际上是字符串,而不是int


如果你有一个
字典
,但你真的对在其中存储任意对象感兴趣,我会把它做成
字典
。因此,您将能够使用强制转换而不是转换,正如Andrew Hare指出的那样,转换将快得多。

等等,您在代码中所称的“强制转换”不是强制转换

如果您正在这样做:

bool success = int.TryParse(map[id][key], out value);
这是一种转换,而不是演员阵容。演员阵容将是:

value = (int) map[id][key];

在这种情况下会失败,因为对象实际上是字符串,而不是int


如果你有一个
字典
,但你真的对在其中存储任意对象感兴趣,我会把它做成
字典
。因此,您将能够使用强制转换而不是转换,正如Andrew Hare指出的那样,转换将要快得多。

如果减少字典查找的数量,您的代码在缓存中的执行速度可能会更快。此外,使缓存
字典
而不是
字典
将避免装箱和拆箱,这也会带来成本

public int GetInt(string id, string key)
{
    int value;
    Dictionary<string, int> cache;

    if (cast_cache.TryGetValue(id, out cache) 
          && cache.TryGetValue(key, out value))
    {
        return value;
    }

    if (int.TryParse(map[id][key], out value))
    {
        this.AddToCache(id, key, value);
        return value;
    }

    throw new InvalidOperationException("Trying to obtain a non-integer value with GetInt().");
}
public int GetInt(字符串id,字符串键)
{
int值;
字典缓存;
if(cast_cache.TryGetValue(id,out cache)
&&cache.TryGetValue(键,输出值))
{
返回值;
}
if(int.TryParse(映射[id][key],输出值))
{
this.AddToCache(id、key、value);
返回值;
}
抛出新的InvalidOperationException(“尝试使用GetInt()获取非整数值”);
}

如果减少字典查找的数量,则代码在缓存中的执行速度可能会更快。此外,使缓存
字典
而不是
字典
将避免装箱和拆箱,这也会带来成本

public int GetInt(string id, string key)
{
    int value;
    Dictionary<string, int> cache;

    if (cast_cache.TryGetValue(id, out cache) 
          && cache.TryGetValue(key, out value))
    {
        return value;
    }

    if (int.TryParse(map[id][key], out value))
    {
        this.AddToCache(id, key, value);
        return value;
    }

    throw new InvalidOperationException("Trying to obtain a non-integer value with GetInt().");
}
public int GetInt(字符串id,字符串键)
{
int值;
字典缓存;
if(cast_cache.TryGetValue(id,out cache)
&&cache.TryGetValue(键,输出值))
{
返回值;
}
if(int.TryParse(映射[id][key],输出值))
{
this.AddToCache(id、key、value);
返回值;
}
抛出新的InvalidOperationException(“尝试使用GetInt()获取非整数值”);
}

> >在这里面有两件事要考虑。首先,我只是想告诉你