【问题标题】:Write a Generic Method that references static generic collections?编写一个引用静态泛型集合的泛型方法?
【发布时间】:2014-06-14 07:10:58
【问题描述】:

我必须编写一个方法,将字符串、int、short、long、float 或 double 作为参数接收,然后为该参数分配一个随机值并将其存储在静态 ConcurrentDictionary 中。性能是一个主要限制因素,所以我不想采用会牺牲性能的设计

例子:

public void StoreVal<T>(T val)
{
   //Check if the val is already in the respective dictionary

   //If not, then create a random value 

   //Store both values in the dictionary
}

我为我期望的每个数据类型创建了一个静态 ConcurrentDictionary。我现在面临的关键问题是如何从泛型方法中引用正确的集合类型,而不必使用一大堆 if/else 语句?

更新:我正在使用 ConcurrentDictionary,因为此方法将由 8 个线程(至少)调用,并且我必须确保传递的参数只有一个映射值。另一个约束是每个数据类型都应该有它自己的映射,即如果 10 (int) -> 25 (int),那么 10 (short) 不需要指向 25 (short) - 这就是为什么我创建了一个单独的 ConcurrentDictionary每种数据类型。

【问题讨论】:

  • 这是一项任务,还是您可以灵活地实施?
  • @hatchet 我已根据您的回复更新了我的问题。

标签: c# generics design-patterns concurrency


【解决方案1】:

如果性能至关重要并且如果可能的输入类型集有限且已知,请考虑使用函数重载而不是泛​​型函数:

public void StoreVal(int val) { // no if needed, you know which Dictionary to use }

public void StoreVal(float val) { // no if needed, you know which Dictionary to use }

public void StoreVal(double val) { // no if needed, you know which Dictionary to use }

// etc ... 

其他解决方案将需要使用分支、强制转换或某种形式的拳击,这无论如何都会降低你的表现。

【讨论】:

  • 拳击的“成本”低。在这种情况下,拳击非常不太可能出现任何明显的性能问题。
  • 我同意,但是对于一些关键应用程序来说,“超低”可能太多了,我个人在生产代码中看到过。 OP无论如何都没有提到上下文。
  • 没有其他可以从根本上显着提高性能的更改的可能性非常非常低。如果这种变化实际上可以产生可测量的差异,那么几乎可以肯定该程序中有数千个更合适的改进。人们喜欢将拳击作为应该不断优化的“昂贵”操作的示例,但它只是没有那么昂贵的操作。它只涉及处理器可以做的一些最简单的事情,真的。
  • 我继续采用此解决方案以保持设计简单并避免任何性能损失。性能是我关心的问题,因为此方法将被调用 2-30 亿次!
【解决方案2】:

如果该值不存在,您可以简单地调用GetOrAdd 来添加该值:

private ConcurrentDictionary<object, object> dictionary;
public void StoreVal<T>(T val)
{
    dictionary.GetOrAdd(val, _ => ComputeRandomValue());
}

【讨论】:

  • 这是否将 int=10 和 short=10 视为两个单独的键?
  • @tunafish24 是的。它们有不同的哈希码
  • @tunafish24 dcastro 是正确的,即使他们有相同的拥有,他们的equals 方法认为他们不同。
【解决方案3】:

我的建议是为每种类型(int、long、short、float 和 double)创建重载。它们都是值类型,因此没有任何共同的祖先。

这就是为什么您在整个基类库中找到的许多方法都提供这些重载的原因。

就目前而言,您的方法的签名将接受任何类型的参数,即使它只能处理其中的一小部分。这打破了principle of least surprise

【讨论】:

  • 重载是我目前的首选。我想知道是否有更优雅的解决方案不会牺牲性能。
猜你喜欢
  • 1970-01-01
  • 2011-06-26
  • 2011-07-14
  • 2012-12-04
  • 2010-10-16
  • 2012-08-26
  • 1970-01-01
  • 2012-02-10
  • 1970-01-01
相关资源
最近更新 更多