

The rendering engine is the single most consequential architectural decision in a charting library. It determines how many points you can plot, whether you see all of them or a resampled approximation, how much memory the chart consumes, how much power it draws, and whether your laptop fan spins up the moment you open a dashboard. Yet most comparison pages reduce this to a single checkmark: 'GPU accelerated — yes / no.' That is not nearly enough information to make an engineering decision.
This page explains the four distinct rendering architectures used by the five most common WPF charting libraries, with specific technical detail on how each one works, what tradeoffs it makes, and what those tradeoffs mean for real applications.
| 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) |
Every WPF chart library on the market falls into one of four architectural categories. Understanding these categories is more important than reading benchmark numbers, because the architecture determines the ceiling of what the library can ever do — no amount of optimization can overcome a fundamentally limiting architecture.
ProEssentials uses Direct3D Compute Shaders — the same GPU technology used in scientific simulation, machine learning inference, and physics engines — to construct the chart image entirely on the GPU. This is architecturally different from using the GPU merely to draw triangles (the game-engine approach).
In a compute shader architecture, the CPU sends your raw data array to GPU memory once. The GPU then runs a shader program that processes every data point in parallel — thousands of GPU cores each handling a slice of the dataset simultaneously. The shader determines the pixel position, color, and visibility of each point, writes the result directly to a GPU texture, and the finished image is presented to the screen.
The critical advantage is that the CPU never iterates over your data. There is no managed loop walking 100 million floats. There is no conversion from float to double. There is no allocation of intermediate objects. The GPU does all the work, and it does it in massively parallel fashion — a modern GPU has 2,000–10,000 cores that all operate simultaneously.
Equally important: ProEssentials only runs this pipeline when data actually changes. When the chart is sitting idle on screen — which is the majority of its lifetime in a dashboard or report — the GPU does exactly zero work. This on-demand model means ProEssentials gets GPU speed when you need it and zero power draw when you don't.
Compute shaders process data in parallel on the GPU. On-demand rendering means zero GPU cost when idle. This combination — GPU speed with on-demand frugality — is unique to ProEssentials among WPF charting libraries.
SciChart uses a game-engine-style rendering pipeline. The library maintains a continuous render loop that fires approximately 60 times per second (every ~16 milliseconds), redrawing the chart on every frame regardless of whether anything has changed.
This architecture comes from the game and trading terminal world, where the screen content is assumed to change constantly and smooth animation is the top priority. SciChart converts your data into GPU vertex buffers and renders them through a traditional graphics pipeline — vertex shader, rasterizer, pixel shader — the same pipeline that draws 3-D game scenes.
The strength of this approach is animation fluidity. Because the loop is always running, any change to data or viewport appears on the very next frame, typically within 16 milliseconds. For applications like financial trading terminals where candles, ticks, and order book depths update constantly, this continuous loop ensures nothing is ever stale.
However, the continuous loop has a cost. SciChart redraws the full chart 60 times per second even when your data hasn't changed. A dashboard with eight SciChart surfaces sitting idle is still generating 480 frames per second of identical output. The GPU stays active, the fan may spin up, and the power draw is constant. SciChart does offer a mechanism to disable the render loop, but it is not the default behavior, and many developers never discover it.
To maintain 60 fps with large datasets, SciChart resamples your data down to approximately 2× the viewport pixel width. At 1920 pixels wide, a 100-million-point dataset is reduced to ~3,840 representative points for rendering. The full data is retained in memory but 99.996 % of it is not drawn in any given frame. This means anomalies, narrow spikes, and fine detail between the sampled points are invisible until you zoom in.
LightningChart uses DirectX at a relatively low level, issuing draw calls through the DirectX API to render chart content. Like SciChart, it maintains a continuous rendering loop, meaning the GPU is active even when the chart data is unchanged.
LightningChart can render data losslessly — it does not resample by default — which is a significant advantage over SciChart for scientific applications where every data point must be visible. However, achieving this at 100-million-point scale requires using the SampleDataSeries type (or the newer SampleDataBlockSeries) with the Non-Bindable chart variant, which abandons WPF data binding and MVVM compatibility.
The continuous rendering loop means LightningChart shares SciChart's power consumption characteristics: GPU stays active when idle, fan may engage on laptops, and embedded or battery-powered deployments accumulate unnecessary thermal and power costs. LightningChart does not expose a simple property to switch to on-demand rendering.
Syncfusion and DevExpress both default to CPU-based rendering. Syncfusion uses WPF's WriteableBitmap — a managed bitmap that the CPU fills pixel by pixel. DevExpress uses a combination of WPF's built-in rendering and GDI+, with an optional DirectX mode and a resampling property (AllowResample) that extends its tested ceiling to roughly 50 million points.
CPU rendering is inherently single-threaded for the drawing phase. While both libraries can prepare data on background threads, the actual pixel-writing happens on the UI thread. This creates a hard ceiling: the chart can only process as many points as a single CPU core can iterate over within a reasonable frame time. In practice, this ceiling is roughly 500,000 to 1,000,000 points before the UI begins to stutter.
The advantage of CPU rendering is simplicity and compatibility. There are no GPU driver requirements, no DirectX dependencies, and no VC++ Redistributable to deploy. For applications with fewer than 100,000 points — which includes most business dashboards, HR analytics, and project management tools — CPU rendering is perfectly adequate and the broad UI suite these vendors offer provides real value.
The distinction between on-demand and continuous rendering is the most underappreciated factor in chart library selection. It has zero impact on benchmark screenshots but enormous impact on real-world deployments — especially laptops, embedded systems, multi-monitor setups, and any application where charts share screen space with other controls.
| 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 |
On-demand rendering is not slower than continuous rendering. ProEssentials achieves the same GPU-accelerated speed as SciChart and LightningChart during active rendering — the compute shader pipeline is just as fast. The difference is what happens between renders. ProEssentials does nothing. SciChart and LightningChart continue redrawing identical content 60 times per second.
When a library claims to 'support' 100 million data points, the critical follow-up question is: does it actually render all 100 million, or does it resample them down to a few thousand and show you an approximation? For business dashboards, resampling is acceptable — the visual shape of the data is preserved. For scientific, medical, and engineering applications, resampling can hide the exact anomaly or spike you need to find.
SciChart uses automatic resampling as its core strategy for large datasets. When ResamplingMode is set to Auto (the default for large data), the library calculates approximately 2 points per horizontal pixel and renders only those representative points. At 1920 pixels wide, a 100-million-point line chart renders roughly 3,840 points. The shape looks correct at the overview zoom level, but fine-grained detail between those 3,840 samples is invisible.
ProEssentials renders every data point. The compute shader processes all 100 million values and determines the correct pixel contribution of each one. If three points map to the same pixel column, the shader correctly computes the min, max, and close values for that column — preserving the visual envelope of the data including spikes and anomalies that resampling would miss.
LightningChart also renders losslessly when using the correct series type (SampleDataSeries with Non-Bindable chart). However, choosing the wrong series type or the Bindable chart variant results in dramatically worse performance — orders of magnitude slower — with no compile-time warning that you've chosen the slow path.
| 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 |
Why this matters: In a medical ECG trace, a single-sample spike might indicate an arrhythmia. In vibration analysis, a narrow resonance peak might span only a few samples. In semiconductor testing, a brief excursion might last microseconds. Resampling hides all of these. Lossless rendering shows them.
Every charting library needs access to your data. The question is whether it reads your existing array or copies everything into its own internal storage. This difference determines memory consumption, load time, and garbage collection pressure — three factors that compound dramatically at scale.
ProEssentials' UseDataAtLocation() stores a pointer to your existing array. The chart never allocates its own copy. This means loading 100 million float values takes effectively zero time (a pointer assignment) and zero additional memory. You modify your source array, call ReinitializeResetImage(), and the chart renders from the updated data immediately.
| 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 |
For a 100-million-point float[] array (400 MB), the total memory footprint is: ProEssentials: 400 MB (your array only). SciChart: 1,200 MB (your array + 800 MB internal double[] copy). Syncfusion: 2,800 MB+ (your array + 2.4 GB of per-point object wrappers). At 100 million points, zero-copy isn't an optimization — it's the difference between an application that runs and one that crashes with OutOfMemoryException.
Real-time charting adds a dimension that static benchmarks miss: sustained throughput over time without memory growth. An application that streams 10,000 samples per second for 8 hours generates 288 million data points. The chart must append new data, discard old data, and render updates — without leaking memory or accumulating GC pressure.
ProEssentials provides built-in circular buffers (set PeData.CircularBuffers = true) that handle the rolling window natively. New data is appended via AppendYData(), old data falls off the trailing edge, and the buffer never grows. Combined with PrepareImages (which batches multiple appends into a single render), this creates an efficient pipeline: collect data on any thread, batch it, render once.
SciChart offers FIFO (First-In-First-Out) mode on its DataSeries, which achieves similar rolling behavior. The difference is that SciChart's continuous render loop redraws the chart 60 times per second regardless of your data rate. If your instrument produces 10 updates per second, SciChart renders 50 redundant frames between each update. ProEssentials renders exactly 10 frames — one per data update — and the GPU is idle the rest of the time.
| 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 |
No single architecture is best for every scenario. Here is a straightforward guide based on what your application actually needs:
| 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' combination of GPU compute shaders, on-demand rendering, lossless data fidelity, and zero-copy data loading is architecturally unique among WPF charting libraries. No other library achieves all four simultaneously. SciChart offers GPU speed but with continuous power draw and data resampling. LightningChart offers lossless rendering but with continuous power draw and MVVM-breaking API constraints. Syncfusion and DevExpress offer simple integration but with lower performance ceilings — Syncfusion hits out-of-memory errors at roughly 16 million points, and DevExpress can push to roughly 50 million with resampling enabled but at extreme memory cost.
For scientific, engineering, medical, industrial, and any application where large datasets, data fidelity, and power efficiency matter — ProEssentials' rendering architecture is the strongest technical foundation available in a WPF charting component.
Side-by-side C# code showing exactly how each library handles 100 million data points.
Read more5-year TCO comparison, support ticket limits, and who actually answers when you need help.
Read moreHow pe_query.py validates AI-generated chart code against the compiled DLL.
Read moreProEssentials support is free, unlimited, and provided directly by the developers who built the rendering engine. Ask us anything about GPU architecture, data loading, or real-time performance.
Contact the ProEssentials Team →Your success is our #1 goal by providing the easiest and most professional benefit to your organization and end-users.
ProEssentials was born from professional Electrical Engineers needing their own charting components. Join our large list of top engineering companies using ProEssentials.
Thank you for being a ProEssentials customer, and thank you for researching the ProEssentials charting engine.