

渲染引擎是图表库中最具影响力的架构决策。它决定了您能绘制多少个点、看到的是全部数据还是重采样近似值、图表消耗多少内存、消耗多少电力,以及打开仪表板时笔记本风扇是否立即转动。然而大多数比较页面将其简化为一个勾选项:'GPU加速——是/否。'这远不足以做出工程决策。
本页详细介绍五个最常见WPF图表库使用的四种不同渲染架构,提供每种架构工作原理、所做的权衡以及这些权衡对实际应用的具体技术细节。
See these world-class charting technologies yourself: clone, build, run the 8M-point real-time zero-copy circular-buffer demo on GitHub.Reproduce these numbers yourself: clone, build, run the 100M-point demo on GitHub.| Architecture | ProEssentials | SciChart | LightningChart | Syncfusion | DevExpress |
|---|---|---|---|---|---|
| GPU technology | Direct3D Compute Shaders | DirectX game-engine pipeline | DirectX immediate-mode | None — CPU only | None (optional DirectX bolt-on) |
| Where chart is built | GPU — compute shader constructs image | GPU — vertex buffer pipeline | GPU — DirectX draw calls | CPU — iterates pixels on CPU | CPU — GDI+ / optional DirectX |
| Frame model | On-demand — renders only when data changes | Continuous — 60 fps game loop always running | Continuous — DirectX render loop always running | On-demand — renders on invalidation | On-demand — renders on invalidation |
| GPU activity when idle | Zero | Full — redraws every 16 ms | Full — continuous refresh | Zero | Zero |
| Data fidelity | Lossless — every point rendered | Resampled — downsampled to viewport width | Lossless | Lossless | Resampled (AllowResample CTP) |
| Data loading | Zero-copy — reads your array in place | Copies into internal DataSeries | Copies via AddSamples | IEnumerable object iteration | SeriesPoint object collection |
| 100 M point render time | ~15 ms | ~ms (renders resampled subset) | ~ms (SampleDataSeries) | Not feasible (OOM at ~16 M) | ~ms (resampled, borderline at 100 M) |
| 100 M point memory overhead | ~0 MB | ~800 MB (duplicates as double[]) | Varies (block allocation) | ~2.4 GB+ (object headers) | ~2.4 GB+ (object headers) |
市场上每个WPF图表库都属于四种架构类别之一。理解这些类别比阅读基准测试数字更重要,因为架构决定了库所能做到的上限——再多的优化也无法克服根本性的架构限制。
ProEssentials使用Direct3D Compute Shader——与科学模拟、机器学习推理和物理引擎中使用的相同GPU技术——在GPU上完全构建图表图像。这与仅使用GPU绘制三角形(游戏引擎方法)在架构上根本不同。
在Compute Shader架构中,CPU将原始数据数组一次性发送到GPU内存。然后GPU运行一个着色器程序,并行处理每个数据点——数千个GPU核心同时处理数据集的各个部分。着色器确定每个点的像素位置、颜色和可见性,将结果直接写入GPU纹理,完成的图像呈现在屏幕上。
关键优势是CPU从不遍历您的数据。没有遍历1亿个float的托管循环。没有从float到double的转换。没有中间对象的分配。GPU完成所有工作,并以大规模并行方式进行——现代GPU有2,000-10,000个核心同时运行。
同样重要的是:ProEssentials仅在数据实际更改时运行此管线。当图表在屏幕上处于空闲状态时——在仪表板或报告中这占其生命周期的大部分——GPU完全零工作。这种按需模型意味着ProEssentials在需要时提供GPU速度,在不需要时零功耗。
Compute Shader在GPU上并行处理数据。按需渲染意味着空闲时GPU成本为零。GPU速度与按需节约的这种组合在WPF图表库中仅ProEssentials独有。
SciChart使用游戏引擎风格的渲染管线。该库维护一个连续渲染循环,大约每秒触发60次(每约16毫秒),无论是否有任何变化都在每帧重绘图表。
这种架构来自游戏和交易终端世界,其中假设屏幕内容不断变化,流畅动画是最高优先级。SciChart将数据转换为GPU顶点缓冲区,并通过传统图形管线——顶点着色器、光栅化器、像素着色器——绘制3D游戏场景的同一管线进行渲染。
这种方法的优势是动画流畅性。因为循环始终在运行,数据或视口的任何更改都会在下一帧出现,通常在16毫秒内。对于蜡烛图、逐笔交易和订单簿深度不断更新的金融交易终端等应用,这种连续循环确保没有任何内容过时。
然而,连续循环有代价。即使数据未更改,SciChart也会每秒60次重绘完整图表。八个SciChart表面处于空闲状态的仪表板仍在每秒生成480帧相同的输出。GPU保持活跃,风扇可能启动,功耗恒定。SciChart确实提供了禁用渲染循环的机制,但这不是默认行为,许多开发者从未发现它。
为了在大数据集上保持60fps,SciChart将数据下采样到大约2倍视口像素宽度。在1920像素宽度下,1亿点数据集被缩减为约3,840个代表性点进行渲染。完整数据保留在内存中,但99.996%在任何给定帧中都不会绘制。这意味着异常、窄尖峰和采样点之间的细节在放大之前是不可见的。
LightningChart在相对较低的层级使用DirectX,通过DirectX API发出绘制调用来渲染图表内容。与SciChart一样,它维护连续渲染循环,这意味着即使图表数据未更改,GPU也处于活跃状态。
LightningChart可以无损渲染数据——默认不进行重采样——这对于需要每个数据点可见的科学应用来说是相对于SciChart的显著优势。然而,要在1亿点规模上实现这一点,需要使用SampleDataSeries类型(或更新的SampleDataBlockSeries)配合Non-Bindable图表变体,这放弃了WPF数据绑定和MVVM兼容性。
连续渲染循环意味着LightningChart与SciChart具有相同的功耗特性:空闲时GPU保持活跃,笔记本上风扇可能启动,嵌入式或电池供电的部署会累积不必要的热量和功耗成本。LightningChart没有提供切换到按需渲染的简单属性。
Syncfusion和DevExpress都默认使用基于CPU的渲染。Syncfusion使用WPF的WriteableBitmap——CPU逐像素填充的托管位图。DevExpress使用WPF内置渲染和GDI+的组合,并提供可选的DirectX模式和重采样属性(AllowResample),将测试上限扩展到约5,000万点。
CPU渲染在绘制阶段本质上是单线程的。虽然两个库都可以在后台线程上准备数据,但实际的像素写入发生在UI线程上。这创建了一个硬上限:图表只能处理单个CPU核心在合理帧时间内能遍历的点数。实际上,这个上限在UI开始卡顿之前约为500,000到1,000,000个点。
CPU渲染的优势是简单性和兼容性。没有GPU驱动程序要求,没有DirectX依赖,没有需要部署的VC++ Redistributable。对于少于100,000个点的应用——包括大多数商业仪表板、人力资源分析和项目管理工具——CPU渲染完全足够,这些供应商提供的广泛UI套件也提供了真正的价值。
按需渲染和连续渲染之间的区别是图表库选择中最被低估的因素。它对基准测试截图的影响为零,但对实际部署有巨大影响——特别是笔记本、嵌入式系统、多显示器设置以及图表与其他控件共享屏幕空间的任何应用。
| Scenario | On-Demand (ProEssentials) | Continuous 60 fps (SciChart / LightningChart) |
|---|---|---|
| Dashboard with 8 charts, no data flowing | 0 frames / sec, ~0 % GPU | 480 frames / sec total (8 × 60), continuous GPU load |
| Real-time monitor, 10 updates / sec | 10 frames / sec, GPU active only during render | 60 frames / sec, 50 frames wasted redrawing identical content |
| Static report opened, user reading | 0 frames after initial paint | 60 frames / sec indefinitely — wasting power while user reads |
| Laptop on battery, multiple charts | Negligible battery draw from charting | Measurable battery drain — GPU never sleeps |
| Embedded kiosk, 24/7 operation | Low heat, low power, long hardware life | Continuous GPU heat, higher power bill, shorter GPU life |
| Smooth zoom / pan interaction | Renders every frame during interaction, stops when idle | Smooth — but was already rendering 60 fps before you touched it |
按需渲染不比连续渲染慢。ProEssentials在活跃渲染期间与SciChart和LightningChart达到相同的GPU加速速度——Compute Shader管线同样快。区别在于渲染之间发生的事情。ProEssentials什么都不做。SciChart和LightningChart继续每秒60次重绘相同的内容。
当一个库声称'支持'1亿数据点时,关键的后续问题是:它实际上渲染了全部1亿个,还是将它们重采样到几千个并显示近似值?对于商业仪表板,重采样是可以接受的——数据的视觉形状得以保留。对于科学、医疗和工程应用,重采样可能隐藏您需要找到的确切异常或尖峰。
SciChart使用自动重采样作为大数据集的核心策略。当ResamplingMode设置为Auto(大数据的默认值)时,库计算每水平像素约2个点,仅渲染这些代表性点。在1920像素宽度下,1亿点折线图渲染约3,840个点。在总览缩放级别下形状看起来正确,但3,840个样本之间的细粒度细节是不可见的。
ProEssentials渲染每个数据点。Compute Shader处理所有1亿个值并确定每个值的正确像素贡献。如果三个点映射到同一像素列,着色器正确计算该列的最小值、最大值和收盘值——保留数据的视觉包络,包括重采样会遗漏的尖峰和异常。
LightningChart在使用正确的系列类型时也可以无损渲染(SampleDataSeries配合Non-Bindable图表)。然而,选择错误的系列类型或Bindable图表变体会导致性能急剧下降——慢几个数量级——且没有编译时警告提示您选择了慢速路径。
| Library | 100 M pts at 1920 px | Data Rendered |
|---|---|---|
| ProEssentials | All 100,000,000 | 100 % |
| SciChart | ~3,840 representative | 0.004 % |
| LightningChart | All (SampleDataSeries) | 100 % |
| Syncfusion | Not feasible | — |
| DevExpress | Resampled subset | Varies |
为什么这很重要:在医疗ECG轨迹中,单个样本尖峰可能表示心律失常。在振动分析中,窄共振峰可能只跨越几个样本。在半导体测试中,短暂偏移可能仅持续微秒。重采样隐藏了所有这些。无损渲染则显示它们。
每个图表库都需要访问您的数据。问题是它是读取您现有的数组还是将所有内容复制到自己的内部存储中。这个差异决定了内存消耗、加载时间和垃圾回收压力——三个在规模增大时急剧复合的因素。
ProEssentials的UseDataAtLocation()存储指向您现有数组的指针。图表从不分配自己的副本。这意味着加载1亿个float值实际上需要零时间(一次指针赋值)和零额外内存。您修改源数组,调用ReinitializeResetImage(),图表立即从更新的数据渲染。
| Factor | ProEssentials Zero-Copy | SciChart Append | LightningChart SampleDataSeries | Syncfusion / DevExpress |
|---|---|---|---|---|
| API call | UseDataAtLocation(array, count) | dataSeries.Append(yValues) | series.AddSamples(array, 0, count) | ItemsSource = collection |
| What happens to your data | Chart stores a pointer — reads your array directly | Entire array copied into internal storage | Copied into series buffer | Each value wrapped in object |
| Memory (100 M float values) | 400 MB (your array only) | 1,200 MB (400 MB source + 800 MB double copy) | 400 MB + block overhead | 2,800 MB+ (400 MB + 2.4 GB objects) |
| Time to load 100 M points | Instant — no copy, just a pointer assignment | Seconds — iterates and copies every value | Sub-second — array copy | Minutes or OOM crash |
| Update workflow | Modify your array → call Reinitialize | Clear + re-Append, or use FIFO with capacity | AddSamples with new data | Reset ItemsSource binding |
| GC pressure | Zero — no managed allocations | Moderate — internal array resizing | Low — array-based | Severe — millions of objects |
对于1亿点float[]数组(400MB),总内存占用为:ProEssentials:400MB(仅您的数组)。SciChart:1,200MB(您的数组 + 800MB内部double[]副本)。Syncfusion:2,800MB+(您的数组 + 2.4GB逐点对象包装器)。在1亿点规模下,零拷贝不是优化——它是应用程序能运行与因OutOfMemoryException崩溃之间的区别。
实时图表增加了静态基准测试遗漏的维度:长时间持续吞吐量且无内存增长。每秒流式传输10,000个样本持续8小时的应用程序会生成2.88亿个数据点。图表必须追加新数据、丢弃旧数据并渲染更新——不能泄漏内存或累积GC压力。
ProEssentials提供内置循环缓冲区(设置PeData.CircularBuffers = true),原生处理滚动窗口。新数据通过AppendYData()追加,旧数据从尾端消失,缓冲区永远不会增长。结合PrepareImages(将多次追加批处理为单次渲染),创建高效管线:在任何线程上收集数据,批处理,渲染一次。
SciChart在其DataSeries上提供FIFO(先进先出)模式,实现类似的滚动行为。区别在于SciChart的连续渲染循环无论您的数据速率如何都每秒60次重绘图表。如果您的仪器每秒产生10次更新,SciChart在每次更新之间渲染50个冗余帧。ProEssentials精确渲染10帧——每次数据更新一帧——其余时间GPU处于空闲状态。
| Real-Time Factor | ProEssentials | SciChart |
|---|---|---|
| Circular buffer | Built-in property | FIFO capacity on DataSeries |
| Append new data | AppendYData / AppendYDataII | dataSeries.Append() |
| PrepareImages (batch) | ✅ Suppresses render until ready | SuspendUpdates / ResumeUpdates |
| Thread safety | Native C — no STA requirement | Must dispatch to UI thread |
| Idle between updates | Zero GPU activity | Still rendering 60 fps |
没有单一架构适合所有场景。以下是基于您的应用实际需求的直接指南:
| Your Application | Best Architecture | Why |
|---|---|---|
| Scientific / engineering with large datasets | ProEssentials — GPU compute + zero-copy | Lossless rendering of 100 M+ points, no memory duplication, on-demand frames |
| Real-time monitoring dashboard | ProEssentials — on-demand + circular buffers | Renders only on new data, native circular buffer, zero idle GPU cost |
| Trading terminal (60 fps animation needed) | SciChart — continuous game loop | Continuous animation suits constantly updating financial tickers |
| Medical device, battery or embedded | ProEssentials — low power on-demand | Zero GPU when idle preserves battery, reduces heat in enclosed systems |
| Business dashboard (< 100 K points) | Syncfusion or DevExpress | CPU rendering sufficient at this scale; broad UI suite provides other controls |
| Signal processing with volume rendering | LightningChart — DirectX + signal tools | Built-in signal tools and volume rendering for specialized DSP workflows |
| Laptop deployment, multiple charts, long sessions | ProEssentials — zero idle cost | 8 idle charts = 0 % GPU. SciChart / LightningChart = 480 fps of wasted renders |
ProEssentials的GPU Compute Shader、按需渲染、无损数据保真度和零拷贝数据加载组合在WPF图表库中架构上独一无二。没有其他库同时实现这四项。SciChart提供GPU速度但伴随持续功耗和数据重采样。LightningChart提供无损渲染但伴随持续功耗和破坏MVVM的API约束。Syncfusion和DevExpress提供简单集成但性能上限较低——Syncfusion在约1,600万点时出现内存不足错误,DevExpress启用重采样可达约5,000万但内存成本极高。
对于大数据集、数据保真度和能效重要的科学、工程、医疗、工业及所有应用——ProEssentials的渲染架构是WPF图表组件中可用的最强技术基础。
我们的首要目标是通过为您的机构和终端用户提供最简单、最专业的服务,达成您的成功。
ProEssentials是由需要自定义图表组件的专业电气工程师创立的。加入使用ProEssentials的顶级工程公司名单。
感谢您成为ProEssentials的客户,也感谢您研究ProEssentials图表引擎。