【问题标题】:Efficient curve plotting using QwtPlotCurve使用 QwtPlotCurve 绘制高效曲线
【发布时间】:2019-07-26 09:34:30
【问题描述】:

我有一个代码库,可以使用 QT 库绘制许多类似范围的曲线。我们正在尝试优化此应用程序的运行时间(因为我们在 CPU 使用率方面遇到了瓶颈)。经过一些分析后,我发现主数据绘图循环从 QWT 库中调用了这个函数:

void QwtPlotCurve::setSamples( const QVector<double> &xData, const QVector<double> &yData )
{
    setData( new QwtPointArrayData( xData, yData ) );
}

每 100 毫秒执行一次。因此,每 100 毫秒有一个 new 调用 QwtPointArrayData 对象,然后有一个 delete 调用之前版本的 QwtPointArrayData 对象,每个范围内的每条曲线。

我的问题是:有没有更好更有效的方法来绘制数据,而无需在每次更新时重新分配数据?

【问题讨论】:

    标签: c++ qt qt5 qwt


    【解决方案1】:

    内存分配在任何程序中都可能导致严重的瓶颈,这取决于它被调用的频率。就性能而言,这是一条非常昂贵的指令,并且应该始终设计一种体系结构,这样就不会发生这种情况。 有很多更好的方法,你绝对不需要为QwtPointArrayData重新分配新内存。看看 qwt 库的例子,例如 oscilloscoperealtime。基本上您可以使用QwtDirectPainter 及其函数drawSeries,它需要QPlotCurve 和您希望绘制的样本数量作为参数。

    https://qwt.sourceforge.io/class_qwt_plot_direct_painter.html

    当然要通过setSamples()或者setRawSamples指令来设置曲线的样本

    https://qwt.sourceforge.io/class_qwt_plot_curve.html#aa51cd3fa00f2a046ca5a9889c5db2413

    这是一种非常有效的方法。但同样,转到库的 examples 文件夹,找到 oscilloscoperealtime 示例,并研究库本身,因为可能有其他可能更适合您的方法。

    编辑: 起初我不明白这是来自图书馆的代码 sn-p。我认为您应该尝试 setRawSamples,因为它应该更有效https://qwt.sourceforge.io/class_qwt_plot_curve.html#afd13c94e23520dacbc37b4d0fd036a8b

    【讨论】:

    • 谢谢@danmar。我会试试setRawSamples。但是,它确实有一个缺点,即我必须在绘图(和程序)期间保持原始数组处于活动状态。如果我不断将新数据添加到数组的末尾,为了从前面清除数据,我必须每次将所有数据复制一个元素。
    • 这应该不是问题,因为您使用的是 QVector 类,该类具有诸如 remove(int) 或 removeFirst() doc.qt.io/qt-5/qvector.html#removeFirst 之类的指令
    • 问题在于QVector::removeFirst() 必须移动并可能动态重新分配向量内的数据,以确保[0] 仍然返回第一个元素并且QVector::constData() 返回一个连续的数组。
    • 嗯,是的,数据重新分配确实发生了,至少根据 QVector 的文档。也许您可以考虑使用动态方法来存储样本,例如类 QList,因为此类在添加/删除/移动向量的元素时引入了较少的开销。但是,为了绘图,您必须将 QList 向量转换为 QVector stackoverflow.com/questions/19569873/…
    猜你喜欢
    • 1970-01-01
    • 2019-08-14
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 2015-02-22
    • 2012-03-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多