0

我需要显示一组信号。每个信号由数百万个样本定义。仅处理样本的集合(用于根据位图大小将样本转换为点)需要大量时间(尤其是在滚动期间)。

所以我实施了某种下采样。我只是跳过一些点:根据信号特征,每 2 点、每 3 点、每 50 点取一次。它极大地提高了速度,但显着扭曲了信号形式。

有没有更聪明的方法?

4

2 回答 2

2

我们在最近的一个应用程序中遇到了类似的问题。我们的可视化(一个简单的折线图)在缩小以查看数据的全部范围时变得过于混乱(大约 7 天的样本,或多或少每 6 秒采集一次样本),因此下采样实际上是要走的路. 如果我们不这样做,缩小就没有多大意义,因为你所看到的只是一大块线条涂抹在屏幕上。

这完全取决于您将如何实施下采样。有两种(简单)方法:在您获取样本时下采样或在显示时下采样。在这两种情况下,真正能大幅提升性能的是正确选择数据源。

假设您有 700 万个样本,而您的查看窗口只对最后一百万个点感兴趣。如果您的实现依赖于 IEnumerable,这意味着 IEnumerable 必须在实际启动之前 MoveNext 600 万次。但是,如果您使用的是针对随机读取优化的东西(想到一个 List),您可以为此实现自己的枚举器,或多或少像这样:

public IEnumerator<T> GetEnumerator(int start, int count, int skip)
{
    // assume we have a field in the class which contains the data as a List<T>, named _data
    for(int i = start;i<count && i < _data.Count;i+=skip)
    {
        yield return _data[i];
    }
}

显然这是一个非常幼稚的实现,但是你可以在 for 循环中做任何你想做的事情(使用基于周围样本的算法来平均?)。但是,这种方法通常会消除信号中的任何极端尖峰,因此请注意这一点。

另一种方法是为不同的范围创建数据集的一些通用版本,当您收到新信号时,它们会自行更新。您通常不需要更新完整的数据集;仅仅更新你的集合的结尾可能就足够了。这允许您对数据进行更高级的处理,但会消耗更多内存。您必须在应用程序中缓存不同的“层”细节。

但是,阅读您的(简短)解释,我认为显示时间优化可能就足够了。如果您进行概括,您的信号总会出现失真。您总是会丢失数据。这取决于您选择的算法如何发生这种失真,以及它会有多明显。

于 2012-04-20T12:17:30.170 回答
1

您需要更好的采样算法,也可以使用 c# 的并行处理功能。请参阅任务并行库

于 2012-04-20T11:56:40.700 回答