Introduction

The sensor-w1therm utility from the WildlifeSystems project has been rewritten from Bash to C to improve start-up time, and provide more efficient sensor readings on Raspberry Pi devices. This report analyses benchmark results comparing the performance of the new C implementation (sensor-w1therm) against the old Bash-based implementation (sensor-ds18b20).

The DS18B20 is a commonly used 1-Wire temperature sensor, and the ability to read multiple sensors efficiently is important for environmental monitoring applications. The WildlifeSystems project uses these sensors for continuous temperature monitoring across multiple nodes.

The source code is available at github.com/Wildlife-Systems/sensor-w1therm.

Background

The DS18B20 Sensor

The DS18B20 is a digital temperature sensor that uses the 1-Wire protocol, allowing multiple sensors to be connected on a single data line. Each sensor has a unique 64-bit ROM code, enabling individual addressing on a shared bus.

Key characteristics:

  • Temperature range: -55°C to +125°C
  • Accuracy: ±0.5°C (from -10°C to +85°C)
  • Resolution: Configurable 9-12 bits (default 12-bit = 0.0625°C)
  • Conversion time: Up to 750ms at 12-bit resolution
  • Communication: 1-Wire protocol with kernel driver support (w1-therm)

The Linux kernel provides native support for 1-Wire devices through the w1 subsystem. The w1-therm driver exposes temperature readings via sysfs, making sensor access straightforward from user-space.

Benchmark Methodology

The benchmark measures the total end-to-end execution time of invoking each binary, including process startup, library loading, sensor reading, and JSON output generation. This reflects real-world usage where the binary is called by an external scheduler.

Tests were conducted with two configurations:

  1. Single sensor: One DS18B20 sensor connected
  2. Four sensors: Four DS18B20 sensors on the same 1-Wire bus

For each configuration:

  • Test hardware: Raspberry Pi (arm64)
  • Number of invocations: n = 100
  • Measurements: Real time, user CPU time, and system CPU time (via /usr/bin/time)
  • Benchmark script: run_system_benchmarks.sh

Part 1: Single Sensor Benchmark

This section compares the performance when reading a single DS18B20 sensor.

Summary Statistics

Single Sensor Benchmark Summary
Implementation Mean Real Time (s) Median Real Time (s) SD Real Time (s) Mean User Time (s) Mean Sys Time (s) Success Rate
C (w1therm) 0.8283 0.82 0.0749 0.0000 0.0301 100%
Bash (ds18b20) 0.9566 0.95 0.0709 0.0217 0.1545 100%

Key finding: With a single sensor, the C implementation averages 0.83 seconds per invocation compared to 0.96 seconds for Bash — a 1.15× speedup.

Distribution of Execution Times

CPU Time Breakdown

The dominant time component for both implementations is I/O wait (waiting for the sensor to complete its temperature conversion). However, the Bash implementation adds overhead in user-space CPU time for shell interpreter loading.

Part 2: Four Sensor Benchmark

This section compares the performance when reading four DS18B20 sensors on the same 1-Wire bus.

Summary Statistics

Four Sensor Benchmark Summary
Implementation Mean Real Time (s) Median Real Time (s) SD Real Time (s) Mean User Time (s) Mean Sys Time (s) Success Rate
C (w1therm) 0.9239 0.88 0.1628 0.0004 0.0992 100%
Bash (ds18b20) 2.1214 2.27 0.6454 0.1321 0.7092 100%

Key finding: With four sensors, the C implementation averages 0.92 seconds per invocation compared to 2.12 seconds for Bash — a 2.30× speedup.

Distribution of Execution Times

CPU Time Breakdown

With four sensors, the I/O wait time increases as each sensor must complete its conversion. The C implementation handles multiple sensors significantly more efficiently than Bash.

Part 3: Scaling Analysis

This section examines how performance scales from one to four sensors.

Scaling observations:

  • C implementation: Time increases by a factor of 1.12× when going from 1 to 4 sensors
  • Bash implementation: Time increases by a factor of 2.22× when going from 1 to 4 sensors
  • The speedup advantage of C over Bash is 1.15× with one sensor and 2.30× with four sensors

Statistical Comparison

To select an appropriate statistical test, we assess normality using the Shapiro-Wilk test:

Single Sensor:

  • C implementation: W = 0.2078, p = 8.94e-21
  • Bash implementation: W = 0.2183, p = 1.18e-20

Four Sensors:

  • C implementation: W = 0.3301, p = 2.74e-19
  • Bash implementation: W = 0.8877, p = 3.92e-07

Given the potential for non-normal distributions, we use the non-parametric Wilcoxon rank-sum test.

  • Single sensor Wilcoxon test: W = 196, p = 6.21e-33
  • Four sensor Wilcoxon test: W = 364, p = 7.02e-30

Both comparisons show statistically significant differences between the implementations (p < 0.05).

Conclusions

The benchmark results demonstrate significant performance improvements from migrating sensor-ds18b20 (Bash) to sensor-w1therm (C):

Single Sensor Performance

Based on 100 invocations:

  • The C implementation averages 0.83 seconds vs 0.96 seconds for Bash — a 1.15× speedup
  • The Bash implementation requires approximately 22ms of user CPU time for shell loading, while C requires effectively 0ms

Four Sensor Performance

Based on 100 invocations:

  • The C implementation averages 0.92 seconds vs 2.12 seconds for Bash — a 2.30× speedup
  • The C implementation shows better scaling with multiple sensors

Resource Efficiency

The C implementation shows dramatic reductions in CPU overhead:

CPU Time Comparison
Metric C (w1therm) Bash (ds18b20)
Mean User CPU (1 sensor) 0.000s 0.022s
Mean Sys CPU (1 sensor) 0.030s 0.154s
Mean User CPU (4 sensors) 0.000s 0.132s
Mean Sys CPU (4 sensors) 0.099s 0.709s

Summary

These results validate the migration from Bash (sensor-ds18b20) to C (sensor-w1therm) for DS18B20 temperature sensor reading. The C implementation provides:

  1. Faster execution: 1.2-2.3× speedup depending on sensor count
  2. Lower CPU overhead: Minimal user-space CPU time vs Bash shell loading
  3. Better scaling: More efficient handling of multiple sensors on the same bus

Example annual impact: For a network with 25 DS18B20 sensors reading once per minute (13,140,000 reads per year), the C implementation saves approximately 19.5 days of wall-clock time and 22.2 days of CPU time annually.