【问题标题】:Is there a design pattern or language feature (c#) to efficiently determine if a set of objects have performed an action是否有设计模式或语言功能 (c#) 可以有效地确定一组对象是否已执行操作
【发布时间】:2017-01-16 05:06:22
【问题描述】:

我在将其表述为标题问题时遇到了一些麻烦。我会尽量简洁,不会遗漏任何内容。

假设你有一个类作为这些组件的大型数据结构中的一个组件。

每个组件都可以有一个或多个“输入”和零个或多个“输出”,它们都是同一类的其他实例。一旦所有输入都通知组件它们已经执行了操作,组件就会执行操作。

class Foo
{
   void checkIn()
   {
        // if all inputs have checked in, takeAction() and then checkIn() with outputs
   }

   void takeAction()
   {
   }
}

这不是一个严格的层次结构,可以有像这样的菱形依赖:

          A
        /   \
       B     C
        \   /
          D

其中 B 和 C 都依赖于 A,而 D 依赖于 B 和 C。D 甚至可以将 A、B 和 C 作为输入。这不是问题的症结所在,但我要指出这一点,因为如果它是一个简单的层次结构,就不会有问题。

这些组件会很多,而且会在实时模拟场景中使用,因此时间效率至关重要。空间效率也很重要,但不如时间重要。

最后,一个组件除了知道它已经完成了它的任务之外,不需要任何来自它的输入的信息。它不需要指向输入的指针,也不需要访问它的数据,而且大多数情况下,它们的关系之所以存在,只是因为它们都在对它们两者外部的数据进行操作,需要完成一个或多个操作才能进行下一个操作.

目前,我的解决方案是让每个组件只存储需要进行的输入总数。

   void checkIn()
   {
        checkInCount++;
        if(checkInCount >= totalCheckInsNeeded)
        {
            performAction();
            // checkIn with outputs
            checkInCount = 0;
        }
   }

这适用于效率和空间,但我不喜欢没有对输入负责。该设计当然是为了确保在初始化数据结构以及创建和连接组件时,所有 checkInCounts 都是正确的,并且永远不会出现输入最终签入两次(从而达到在所有输入都签入之前的 totalCheckInsNeeded)。我只是不喜欢如果初始化过程中存在错误,那么在可能包含数十万个组件的大型结构中追踪可能真的很困难。

我想到的任何可以缓解这种问责制问题的解决方案都将涉及检查输入列表的方式,从表面上看,这在时间和空间上的效率都大大降低。我只会在调试构建的输入解决方案列表中添加,但如果存在未知错误,我宁愿有一种方法来检测问题并优雅地失败,而不是让程序突突地忘记它已经坏了状态。

我希望要么是我没有考虑过的设计模式,要么是我还不知道的 C# 语言特性。 (从 C++ 背景接触 C# 相对较新,并且仍在学习来龙去脉)

【问题讨论】:

  • 对一个组件可以拥有多少依赖项(输入)有任何限制吗?
  • @SergeyL - 没有硬性限制 - 大多数输入在 3 到 10 个之间。可能存在 20 个或更多的情况,但它们将是异常值,如果有 30 个或更多,则可能是在性能测试期间,而不是实际或正常使用。

标签: c# performance design-patterns processing-efficiency memory-efficient


【解决方案1】:

由于您主要关心的是单个输入的多次签入,因此您可以使用带有位掩码而不是计数器的方法。很简单,您可以使用 int32 或 int64 将您限制为 32/64 输入。当输入完成时,它会清除连接组件中的相应位。如果它试图清除已清除的位,则您会遇到错误情况。由于所有位都为零,这意味着所有输入都已处理,您可以触发操作。如果需要,可以使用字节数组轻松覆盖 32/64 限制。有一个困难 - 如何定义相应的位?您可以在输入元素中保留一个位数。如果此输入连接到多个组件怎么办?它应该在所有连接的组件中具有相同的位数。如果您能保证在模型创建过程中可以这样设置所有的位数而不会发生冲突,这将是最简单的解决方案。

     A   B         A must have the same bit number in QWR, B in RTE
    /|\ /|\        A's and B's bit number should not conflict in R
   Q W R T E

更昂贵的内存方法是为每个链接分配单独的位号。这意味着您应该在每个输入中都有一个大小为字节的数组。本例中 A 中的 3 个字节。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-10
    • 2012-03-31
    • 2016-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多