Skip to main content

MD Trajectory SASA Benchmarks

Performance comparison of SASA calculation on molecular dynamics trajectories.

Note: Times include trajectory loading and SASA calculation. All tools use 100 test points per atom (Shrake-Rupley algorithm).

TL;DR

DatasetAtomsFrameszsasa CLI bitmask (f32, 10t)vs MDTrajvs mdsasa-boltRSS
5wvo_C3,8581,0010.78s30x5.8x17 MB
6sup_A33,3771,0016.92s132x8.5x113 MB
5vz0_A17,91010,00138.04s>2h (timeout)>2h (timeout)63 MB
  • zsasa CLI bitmask is the fastest variant: ~2x faster than standard zsasa on large systems
  • Memory is constant with frame count (streaming I/O) — 63 MB for 10K frames vs Python tools using 3–6 GB
  • MDTraj and mdsasa-bolt timed out (>2h) on the 10K-frame dataset that zsasa completes in 38 seconds

Test Environment

ItemValue
MachineMacBook Pro
ChipApple M4 (10 cores: 4P + 6E)
Memory32 GB
OSmacOS 15.3.2 (Darwin 24.6.0)

Implementations

ToolLanguageThreadingI/ONotes
zsasa CLIZigConfigurableNative XTC readerf32/f64 precision, streams frames
zsasa CLI bitmaskZigConfigurableNative XTC readerLUT bitmask, streams frames
zsasa.mdtrajPython/ZigConfigurableMDTraj (C)MDTraj loads trajectory, zsasa computes SASA
zsasa.mdtraj bitmaskPython/ZigConfigurableMDTraj (C)LUT bitmask variant
zsasa.mdanalysisPython/ZigConfigurableMDAnalysisMDAnalysis loads trajectory, zsasa computes SASA
zsasa.mdanalysis bitmaskPython/ZigConfigurableMDAnalysisLUT bitmask variant
MDTrajPython/CSingle-threadedMDTraj (C)shrake_rupley, no parallel option
mdsasa-boltRustAll cores (rayon)MDAnalysis/PythonRustSASA via Python bridge

Results

6sup_A_analysis (Large: 33,377 atoms, 1,001 frames)

Benchmark: warmup=1, runs=3, threads=1,8,10.

10-Thread Comparison

ToolTime (s)FPSvs MDTrajvs mdsasa-boltRSS
zsasa CLI (f32, bitmask)6.92145132.4x8.5x113 MB
zsasa CLI (f64, bitmask)7.16140127.9x8.2x120 MB
zsasa.mdtraj bitmask7.31137125.3x8.0x1.5 GB
zsasa.mdanalysis bitmask7.71130118.8x7.6x988 MB
zsasa CLI (f32)14.796861.9x4.0x111 MB
zsasa.mdtraj15.596458.7x3.8x1.6 GB
zsasa CLI (f64)15.796358.0x3.7x116 MB
zsasa.mdanalysis17.115953.5x3.4x1.0 GB
mdsasa-bolt58.531715.6xbaseline10.9 GB
MDTraj915.571.1baseline874 MB

Key findings:

  • zsasa CLI bitmask (f32) is 132x faster than MDTraj, 8.5x faster than mdsasa-bolt
  • Bitmask variants are ~2.1x faster than standard zsasa (6.92s vs 14.79s)
  • mdsasa-bolt uses 10.9 GB RAM vs zsasa CLI's 113 MB (96x difference)
Tool Comparison (10t)Memory
barmemory

5vz0_A_protein (Medium: 17,910 atoms, 10,001 frames)

Benchmark: warmup=1, runs=3, threads=1,8,10.

MDTraj and mdsasa-bolt timed out at the 2-hour limit (--timeout 7200). MDTraj is too slow for 10K frames of this size; mdsasa-bolt likely exhausted memory (see mdsasa-bolt Performance).

10-Thread Comparison

ToolTime (s)FPSRSS
zsasa.mdtraj bitmask37.412675.8 GB
zsasa.mdanalysis bitmask37.772653.2 GB
zsasa CLI (f32, bitmask)38.0426363 MB
zsasa CLI (f64, bitmask)38.9925667 MB
zsasa.mdtraj81.551235.8 GB
zsasa CLI (f32)82.5812161 MB
zsasa.mdanalysis82.691213.1 GB
zsasa CLI (f64)86.0811664 MB

Key findings:

  • Bitmask variants ~2.1x faster than standard (38s vs 83s)
  • zsasa CLI processes 10,001 frames in 38 seconds (263 FPS) with only 63 MB RAM
  • Python bindings slightly faster than CLI on bitmask (trajectory pre-loaded vs streaming), but use 50–90x more memory
Tool Comparison (10t)Memory
barmemory

5wvo_C_analysis (Small: 3,858 atoms, 1,001 frames)

Benchmark: warmup=1, runs=3, threads=1,8,10.

10-Thread Comparison

ToolTime (s)FPSvs MDTrajvs mdsasa-boltRSS
zsasa CLI (f32, bitmask)0.781,29130.0x5.8x17 MB
zsasa CLI (f64, bitmask)0.791,26329.4x5.6x18 MB
zsasa.mdtraj bitmask0.881,14426.6x5.1x210 MB
zsasa.mdanalysis bitmask1.2083819.5x3.7x172 MB
zsasa.mdtraj1.6461214.2x2.7x195 MB
zsasa CLI (f32)1.6959313.8x2.6x14 MB
zsasa CLI (f64)1.7756813.2x2.5x15 MB
zsasa.mdanalysis1.9950511.7x2.2x166 MB
mdsasa-bolt4.472245.2xbaseline1.4 GB
MDTraj23.2943baseline156 MB

Key findings:

  • On small systems, bitmask advantage is smaller (~2.2x vs ~2.1x on large)
  • zsasa CLI bitmask processes 1,001 frames in under 1 second at 1,291 FPS
  • Even on a small system, mdsasa-bolt uses 1.4 GB vs zsasa CLI's 17 MB
Tool Comparison (10t)Memory
barmemory

Memory Usage

Tool5wvo_C (4k atoms, 1k fr)5vz0_A (18k atoms, 10k fr)6sup_A (33k atoms, 1k fr)
zsasa CLI bitmask17 MB63 MB113 MB
zsasa CLI14 MB61 MB111 MB
zsasa.mdanalysis bitmask172 MB3.2 GB988 MB
zsasa.mdtraj bitmask210 MB5.8 GB1.5 GB
MDTraj156 MB874 MB
mdsasa-bolt1.4 GB10.9 GB
  • zsasa CLI memory scales with atom count, not frame count (streaming I/O)
  • Python tools load the entire trajectory into memory — scales linearly with frames
  • For 5vz0 (10k frames, 18k atoms): zsasa CLI uses 63 MB while Python bindings use 3–6 GB

Bitmask Variants

The _bitmask variants use LUT bitmask neighbor lists:

  • ~2.1x faster than standard zsasa across all system sizes
  • Minimal memory overhead for CLI variants (~2 MB extra)
  • Python bitmask bindings are faster but still load full trajectories into memory
  • On small systems (5wvo, 4k atoms), bitmask advantage is ~2.2x; on large systems (6sup, 33k atoms), ~2.1x

mdsasa-bolt Performance

mdsasa-bolt (RustSASA via Python) shows high memory usage across all datasets:

Datasetmdsasa-bolt RSSzsasa CLI RSSRatio
5wvo_C (4k atoms)1.4 GB17 MB82x
6sup_A (33k atoms)10.9 GB113 MB96x

On the previous 10k-frame dataset (6sup_R1), mdsasa-bolt showed severe performance degradation (147x slower than zsasa), becoming slower than single-threaded MDTraj. This pattern is consistent with memory-bound scaling issues.

SASA Validation

Per-frame total SASA compared against MDTraj shrake_rupley as baseline, using 5wvo_C (3,858 atoms, 1,001 frames).

Note on baseline: MDTraj and zsasa use different sphere point placement (MDTraj uses reversed winding order). This causes small systematic differences that diminish with increasing test points. Bitmask error is independent of point count due to the LUT approximation. Plots use zoomed axes — the spread appears larger than it is in practice.

R² vs MDTraj by Test Points

Tool100 pts200 pts500 pts1000 pts
zsasa CLI (f64)0.87160.96640.99380.9983
zsasa CLI (f32)0.87160.96640.99380.9983
zsasa.mdtraj0.87160.96640.99380.9983
zsasa.mdanalysis0.97240.98850.97180.9602
zsasa CLI bitmask (f64)0.39800.64370.75370.7916
zsasa CLI bitmask (f32)0.39810.64380.75370.7917
  • Standard variants converge rapidly: R² > 0.99 at 500 points, > 0.998 at 1000 points
  • Bitmask variants plateau around R² ~0.79 regardless of point count (LUT approximation error)
  • f32 and f64 produce virtually identical results
  • zsasa CLI f64 vs zsasa.mdtraj: R² = 1.000 (identical SASA engine, different I/O path — max error 0.008%)

ΔR² (Frame-to-Frame SASA Changes)

ΔR² measures how well frame-to-frame SASA changes (ΔSASA) correlate — which is what matters most in MD analysis.

Tool100 pts200 pts500 pts1000 pts
zsasa CLI (f64)0.89180.95270.98950.9962
zsasa CLI (f32)0.89180.95270.98950.9962
zsasa CLI bitmask (f64)0.89020.95010.98720.9941
zsasa CLI bitmask (f32)0.89020.95020.98740.9941
  • Bitmask ΔR² is nearly identical to standard — the systematic offset from LUT cancels out in frame differences
  • At 100 points: bitmask ΔR² = 0.890 vs standard ΔR² = 0.892 (negligible gap)
  • At 1000 points: both converge to ΔR² > 0.994

Practical Significance

The absolute R² values for bitmask may look low (~0.79), but the scatter plots use zoomed axes that exaggerate the spread. The actual max per-frame error is 1.5–3%, and more importantly, the ΔR² shows that frame-to-frame trends are tracked with >0.99 correlation at 500+ points — even for bitmask.

For MD trajectory analysis where SASA trends and changes matter more than absolute values, bitmask accuracy is sufficient. If precise absolute values are needed, use the standard f64 variant.

Validation grid

XTC reader consistencyBitmask comparison
xtcbitmask

Running Benchmarks

# Run benchmark
./benchmarks/scripts/bench_md.py \
--xtc trajectory.xtc \
--pdb topology.pdb \
--name my_bench \
--threads "1,8,10"

# Specific tools only
./benchmarks/scripts/bench_md.py \
--xtc trajectory.xtc \
--pdb topology.pdb \
--name my_bench \
--tool zig --tool zig_bitmask --tool zsasa_mdtraj

# Analysis
./benchmarks/scripts/analyze_md.py all --name my_bench
./benchmarks/scripts/analyze_md.py summary --name my_bench
./benchmarks/scripts/analyze_md.py bar --name my_bench
./benchmarks/scripts/analyze_md.py memory --name my_bench

Options

OptionDescriptionDefault
--xtcXTC trajectory file(required)
--pdbTopology PDB file(required)
--name, -nBenchmark name(required)
--threads, -TThread counts: 1,4,8 or 1-101,8
--runs, -rNumber of benchmark runs3
--warmup, -wNumber of warmup runs1
--stride, -sFrame stride1
--n-pointsTest points per atom100
--tool, -tTool: zig, zig_bitmask, zsasa_mdtraj, zsasa_mdtraj_bitmask, zsasa_mdanalysis, zsasa_mdanalysis_bitmask, mdtraj, mdsasa_bolt (repeatable)all
--output, -oOutput directoryresults/md/<n_points>/<name>
--dry-runShow commands without runningfalse

Notes

  • f32 and f64 precision produce nearly identical timing (~3–5% difference)
  • SASA accuracy and XTC reader consistency validated in validation.md
  • mdsasa-bolt "all" = 10 threads on this system