Original Research
Frontiers in Computer Science ·
Volume 8 - 2026 | https://doi.org/10.3389/fcomp.2026.1925314
Experimental evaluation of compression algorithms for memory-constrained embedded systems
- Tomáš Bača1*corresponding author
- Lukáš Formanek1
- Peter Ševčík1
- Ondrej Karpiš1
- Department of Technical Cybernetics, Faculty of Management Science and Informatics, University of Žilina, Žilina, Slovakia
Abstract
Embedded systems are constrained by limited flash memory, RAM (random access memory), and processing power, making efficient local data storage and transmission challenging. This study evaluates the suitability of several lossless compression algorithms for resource-constrained embedded platforms and assesses how data representation influences compression performance. LZW, Heatshrink, LZ4, FastLZ, and Miniz were evaluated directly on an STM32U575ZI microcontroller (Arm Cortex-M33, 160 MHz). A 104,067-byte sensor dataset comprising repetitive time-series measurements of soil and ambient temperature, humidity, battery voltage, timestamps, and identifiers was used as the test workload. The dataset was stored in three formats: CSV (comma-separated values) (104,067 bytes), binary (33,576 bytes), and bit-packed binary (26,581 bytes). Compression ratio, execution time, and total application RAM consumption, including input and output buffers, were measured. Miniz achieved the highest compression efficiency, reducing the 33,576-byte binary dataset to 11,352 bytes (33.81% of the original size). The fastest compression was obtained with LZ4 configured with acceleration = 16, which compressed the bit-packed representation in 9.437 ms and produced a 25,692-byte output. Among configurations selected for minimum compressed output, FastLZ achieved the shortest execution time at 31.653 ms. When total RAM consumption was evaluated consistently, including all required buffers, LZ4 operating on the bit-packed representation required the least memory among the minimum-output configurations, consuming 58,496 bytes. The results demonstrate significant trade-offs between compression ratio, execution speed, and memory requirements in embedded environments. Data representation substantially influences compression effectiveness, with binary and bit-packed formats generally improving efficiency over CSV. The findings provide practical guidance for selecting compression algorithms in resource-constrained embedded systems, where minimizing storage, execution time, or memory usage may be prioritized depending on application requirements.
Keywords
1 Introduction
Data compression algorithms are useful in many areas of embedded systems (Kamal, 2008; Zurawski, 2018; Ehrlich and Radke, 2013), such as:
- Data storage—Microcontrollers have access to a limited amount of Flash and RAM memory; therefore, storing data in a memory-efficient way is necessary in many applications.
- Wired/wireless data transmission—Smaller data can be transmitted faster through communication protocols. This reduces energy consumption (especially in wireless communication) by decreasing the time the microcontroller spends in active mode with activated communication protocol circuitry. Additionally, it enables the microcontroller to enter sleep mode more quickly, which further reduces energy consumption.
Embedded devices have more constrained system resources than general-purpose computers; therefore, not all available compression algorithms are suitable. Considering criteria such as low memory footprint, availability of embedded implementations, and other factors, lossless byte-stream compression algorithms LZW, Heatshrink, LZ4, FastLZ, and Miniz were chosen (Sharma et al., 2025; Kulkarni et al., 2025). Comparison of text (CSV), binary, and bit-packed binary representations was also performed.
All compression tests were performed on a dataset containing timestamps and sensor data (temperature, humidity, and battery voltage), which exhibit repetitive patterns.
The first section contains a literature review of scientific papers focused on compression algorithms. The majority of articles in the literature reviewed focused either on source-code compression or on general data compression performed on general-purpose computers. Their findings are not directly applicable to compressing user data on embedded systems with limited memory and processing capabilities. Therefore, the primary aim of this study is to evaluate multiple compression algorithms directly on an embedded platform (the STM32 microcontroller).
Our research differs from the previously published works by providing an experimental evaluation of the compression ratio, execution time, and RAM requirements of several compression algorithms (LZW, Heatshrink, LZ4, FastLZ, and Miniz) implemented in C and evaluated directly on the STM32U575ZI microcontroller. In all experiments, datasets containing numerical data were compressed in three formats: CSV file, binary file, and bit-packed binary file.
Additionally, the designed and publicly available compression algorithm evaluation framework, written in the C programming language, can be used to assess the compression ratio, execution time, and RAM requirements of the evaluated algorithms (LZW, Heatshrink, LZ4, FastLZ, and Miniz) on user-specific datasets. This provides a simple and practical tool for selecting the most appropriate compression algorithm for a given application based on its expected dataset structure and the primary evaluation metrics (smallest compressed file size, fastest compression time, or lowest RAM usage). The designed framework simplifies the development of data compression applications on embedded systems and simultaneously facilitates the evaluation of different dataset structures to identify the most suitable compression approach for a given application.
The second section describes principles on which the compression algorithms are based.
The third section presents experimental conditions, the results of the experiments, and their evaluation.
Based on the experiments conducted and their evaluation, the following findings were identified.
The compression algorithm that produced the smallest compressed output was Miniz (11,352 bytes) when executed on the dataset stored in binary format. Within the binary-representation minimum-output comparison, Miniz also had the longest compression time (219 ms 512 μs) and the largest total application RAM requirement (113,216 bytes).
The fastest configuration across all tests was LZ4 with acceleration = 16 on the bit-packed representation (9 ms 437 μs; 25,692-byte output). Across all minimum-output configurations, FastLZ on the binary representation had the shortest compression time (31 ms 653 μs); its output was 17,591 bytes and its total application RAM was 74,512 bytes.
After the common input and output buffers were included consistently, the minimum total application RAM among configurations selected for minimum compressed output was obtained by LZ4 on the bit-packed representation (58,496 bytes). Heatshrink on the same representation produced the second-smallest compressed output (13,941 bytes), required 58,740 bytes of total application RAM, and had a compression time of 113 ms 335 μs.
The results of the compression algorithm evaluation are strongly dependent on the initial dataset, and our findings represent only a baseline comparison that can serve as a practical guideline.
Based on the results, the following two findings were observed for the numerical time-series dataset evaluated in this study.
- For the numerical time-series dataset evaluated in this study, the binary representation substantially reduced the input size relative to CSV before compression.
- For the tested dataset, applying bit packing before compression reduced compression effectiveness and resulted in a larger compressed-to-input size ratio than the ordinary binary representation. This was associated with reduced byte alignment and the loss of recurring byte-level patterns used by the evaluated compressors.
These two findings are consistent with the results presented in Keskin et al. (2023); Hubacz and Trybus (2022).
The fourth section presents a parametric model linking payload size to transmission time and transmit-state energy. Its worked example uses hypothetical communication-interface parameters and does not represent an experimental measurement of energy consumption.
2 Literature review
Compression algorithms are used in many applications; however, currently published research papers primarily address source-code compression, compression on edge servers, and text or multimedia file compression on general-purpose computers. The number of papers published in the area of user-data compression performed directly on embedded devices is very limited, which was one of the main reasons our research team decided to focus on this topic.
The three scientific papers closest to our area of research are summarized in the Table 1.
Table 1. Comparison with the studies most closely related to the present work.
| Study | Platform | Dataset | Algorithms | Metrics | Main limitation for the present research question | How the present work differs |
|---|---|---|---|---|---|---|
| Piatkowski et al. (2024) | STM32F411 CE with three radio modules | One day of BME280 text records and images | Huffman, LZ77, LZ78, LZW, JPEG | Transmission energy and compressed size | Algorithm parameters were fixed; binary representations and RAM were not compared | Five byte-stream compressors, parameter sweeps, three represen- tations, execution time, and total RAM on STM32U575 ZI |
| Kadhum Idrees et al. (2025) | ESP32, Teensy 4.0, RP2040 | Multiple IoT data types | SZ4IoT, LTC, WQT-RLE, K-RLE | Ratio, distortion, time, energy | Lossy methods allow reconstruction error and do not address exact byte recovery | Lossless compression of the selected representation, including the explicit exception introduced by voltage clamping during preprocessing |
| Guberović et al. (2019) | PC and ESP32-WROOM32 | UMass Smart* 2017 metering data in batches | Elias, Golomb–Rice, Exponential–Golomb, variable-byte variants | Efficiency, time, power | Different code families and batched data; no comparison of CSV, binary, and bit-packed representations | Dictionary and DEFLATE-family implemen- tations evaluated across representations with parameter and RAM trade-offs |
In Piatkowski et al. (2024), the impact of lossless data compression on the energy consumption required for data transmission on IoT devices powered by battery-based energy storage systems was investigated. The study evaluated the canonical Huffman, Lempel–Ziv 77, Lempel–Ziv 78, and Lempel–Ziv–Welch algorithms on a text file containing temperature, pressure, and relative humidity data collected by the BME280 sensor over a 1-day period. Each entry also included a timestamp and the sensor-node name. Based on the experiments, the best results were obtained using the Lempel–Ziv 78 compression algorithm.
The study also evaluated the JPEG compression algorithm on image files with dimensions of 160 × 120 px, 320 × 240 px, and 640 × 480 px.
All experiments and energy-consumption measurements were conducted on an embedded system consisting of an STM32F411CE microcontroller and three different wireless transmission modules: FS1000A, nRF24L01+, and ESP-01.
During the experiments, the dataset containing text data was divided into smaller subsets (datasets containing samples from specific hours of the measured data). The power consumption of each transmission module was measured in two stages: in the first stage, no compression algorithm was applied; in the second stage, standalone compression algorithms were used. With the FS1000A module, the lowest energy consumption was achieved using the Lempel–Ziv 78 algorithm on 6-h data samples and the Lempel–Ziv 77 algorithm on 4-h data samples. With the nRF24L01+ module, the lowest energy consumption was obtained using the Lempel–Ziv 78 algorithm. With the ESP-01 module, the lowest energy consumption was achieved using the Lempel–Ziv 77 algorithm.
The study also mentions the potential use of a TinyML AI model to predict which data are critical and must be transmitted immediately (e.g., error conditions in the controlled system) and which data can be buffered for later compression and transmission.
The research goal of our study differs from Piatkowski et al. (2024) in the following primary points:
- Compression algorithms and parameter variation—Our study evaluates the compression algorithms LZW, Heatshrink, LZ4, FastLZ, and Miniz, including variations in their parameters during the experimental evaluation of compression ratio, execution time, and RAM requirements. In Piatkowski et al. (2024), the parameters of the compression algorithms were fixed at the beginning of the tests and were not changed throughout the experiments.
- Dataset storage formats—In Piatkowski et al. (2024), compression was evaluated only on a dataset stored as a text file. No evaluation of compression ratio, execution time, or RAM requirements was performed for datasets stored in binary format or bit-packed binary format, even though the dataset storage type materially affects these metrics.
- Primary research focus—The main objective of Piatkowski et al. (2024) was to measure the energy consumption of different wireless transmission modules with and without compression. However, the study did not evaluate how changes in compression-algorithm parameters affect compression ratio, execution time, and RAM usage, even though these parameters directly influence the resulting performance metrics.
In Kadhum Idrees et al. (2025), the lossy compression algorithm named SZ4IoT was proposed. This algorithm offers a high compression ratio while carefully balancing the trade-off between compression ratio and data distortion. It was designed specifically for IoT devices exchanging data within a wireless network. SZ4IoT was tested against three other lossy compression algorithms: Temporal Compression (LTC), Wavelet Quantize Threshold with RLE (WQT-RLE), and K Run-Length Encoding (K-RLE). Based on the experimental results, SZ4IoT outperformed the other algorithms in terms of compression ratio, energy consumption, and compression time.
The experimental evaluation of the compression algorithms was performed on the ESP32 microcontroller, the Teensy 4.0 IoT microcontroller, and the Raspberry Pi Pico (RP2040) microcontroller, all of which were programmed in the C programming language using the Arduino IDE environment.
Our study focuses on lossless compression algorithms, i.e., algorithms in which decompression yields exactly the same dataset that was originally compressed. Lossless compression is necessary in applications where no data can be lost, such as data loggers or long-term measurement projects whose data must be further processed after collection. In such applications, the use of lossy compression can alter the final processing results. Consequently, the lossy compression algorithms SZ4IoT, LTC, WQT-RLE, and K-RLE are not suitable for our area of research.
In Guberović et al. (2019), several lossless compression algorithms (Elias gamma, delta codes, Golomb–Rice code, adaptive Golomb–Rice code, Exponential–Golomb code, adaptive Exponential–Golomb code, and variable-byte code) were tested on data gathered in smart metering applications. During the experiments, the compression efficiency, processing time, and microcontroller power consumption (measured using the INA219 sensor) of the different compression algorithms were determined. All algorithms were first implemented in the Python programming language and evaluated on a general-purpose computer running Windows 10 in order to determine their properties (compression efficiency and processing time) on the selected dataset (UMass Smart* Dataset–2017). In the second phase, the algorithms that demonstrated good properties on the dataset were reimplemented in C++ and evaluated on an ESP32-WROOM32 embedded device, with the dataset divided into batches to prevent overflowing the microcontroller's RAM memory.
Our study focuses on the evaluation of different lossless compression algorithms with variations in their parameters on an STM microcontroller. Additionally, the compression properties measured during our experiments include compression efficiency, processing time, and RAM memory usage.
All subsequent papers are part of the general literature review on compression algorithms, used primarily outside embedded systems. They are included to provide a broader overview of compression-algorithm applications.
2.1 Source code compression
This form of compression can be used to reduce the memory requirements of the user code, but not the size of data files stored in memory or transferred through communication protocols.
In Ozturk et al. (2005), a code compression strategy based on the control flow graph representation of executable binaries stored in Flash memory is described. Binaries consist of compressed blocks of data; during code execution, only those blocks that will be needed in the near future are decompressed and moved to RAM. In other words, only actively used blocks are decompressed and placed in RAM, and once they are no longer needed, they are compressed again to reduce memory requirements.
In Xie (2003), source code compression using Tunstall coding and arithmetic coding is described (both are based on a variable-to-fixed coding scheme). The article also calculates the compression lower bound using the following models:
- Static fixed model—assumes that ones and zeros in source code have an independent distribution. This model is not application-specific, and probabilities of 0 and 1 are calculated based on the analyzed example code.
- Semi-adaptive Markov model—defined by model depth and model width; each state is connected to other states via two transitions. When calculating the compression lower bound, we start at state 0. If the next input bit is 0, the left transition is taken; if it is 1, the right transition is taken.
In Li and Nowick (2005), a source code compression method based on Huffman encoding with higher-order correlations is described. It uses architecture-orientated models in which a fast and simple hardware decoder is placed between instruction memory and cache memory. This decoder is used only when cache memory refills (an approach called decompress on cache refill). Thanks to this approach, high compression efficiency can be achieved while requiring no modification of the compiler or processor core, since compression is performed after compilation.
Traditional code compression works on fixed-size blocks; however, this approach limits compression efficiency. In Lin et al. (2020), an approach called branch block is described. A branch block is a series of instructions found between two consecutive possible branch targets. With this approach, branch blocks have dynamic length, allowing better compression efficiency. The article also includes descriptions of multiple branch-block-based methods together with dictionary-based code compression methods.
2.2 Data compression
In Lu et al. (2020), evaluation of gzip, bzip2, LZMA, and Zstd compression algorithms executed on an edge server (desktop computer) is presented. The server transfers data collected from IoT devices through HTTP or MQTT protocols to the cloud for storage or further processing. The authors implemented a tool called ZipMate, which is middleware that chooses the most appropriate compression algorithm based on CPU, network bandwidth, and storage limitations on the edge server. This is done by evaluating compression algorithms on a small subset of the transferred dataset. In this approach, data compression is not performed directly on a resource-constrained IoT device but on a more powerful edge server.
In Hosseini (2025), various data compression algorithms, their applications, performance evaluations, and current research approaches are described. Lossless compression algorithms include Huffman encoding, Tunstall coding, run-length encoding, the Lempel-Ziv algorithm, and arithmetic coding. Lossy compression algorithms include vector quantisation and scalar quantisation.
Performance evaluation on two text files was performed using the Lempel-Ziv algorithm and Huffman coding. Based on published results, Huffman coding produced smaller compressed file sizes.
In Rodrigues et al. (2022), both lossy and lossless compression algorithms are described, along with principles on which they are based (Run-Length Encoding, Huffman Coding, Lempel-Ziv-Welch algorithm, and Shannon-Fano coding). The article also includes evaluations of compression time and compressed file size for different lossless compression algorithms applied to text, image, and audio files.
For text file evaluation, 10 text files with different sizes and varying occurrences of repetitive patterns were used. Huffman, LZW, Shannon-Fano, and run-length encoding algorithms were evaluated. The best results were obtained with the LZW algorithm.
For image file evaluation, 10 bitmap images with different resolutions and sizes were used. Run-length encoding and Shannon-Fano encoding were evaluated, with Shannon-Fano achieving the best results.
For audio file evaluation, 10 two-channel WAV files with different sizes were used. Huffman and Shannon-Fano encoding were evaluated, with Shannon-Fano producing the best results.
In Jayasankar et al. (2021), different compression algorithms used for text, image, audio, and video files are described. Additionally, mathematical metrics of compression algorithms are discussed, and future research directions are outlined. The article serves as a state-of-the-art overview of compression algorithms up to 2019.
In Nikam and Dhande (2023), principles of both lossy and lossless compression algorithms for audio, text, video, and image files are described.
In Yoon et al. (2020), compression algorithms used to reduce the amount of data stored in and read from DRAM memory in high-end multimedia applications (such as 8K HDR video) are discussed. The key issue described in the paper is that integrated circuit development for high-frequency and high-resolution video capture progresses faster than DRAM development. As a result, insufficient DRAM bandwidth, overheating, and high-power consumption become major problems in mobile devices with limited battery capacity and cooling systems. The article focuses on lossless compression algorithms that allow decompression without any loss of quality while reducing DRAM bandwidth requirements, leading to lower temperatures and power consumption.
Other relevant scientific articles on compression include Hwang et al. (2021), Ko et al. (2021), Auli-Llinas (2023), and Yang et al. (2010).
3 Lossless data compression algorithms for low-power devices
This study evaluates byte-stream compression at the application layer. All five tested algorithms are lossless with respect to the byte representation supplied to the compressor: decompression reproduces that representation exactly. This definition does not make a preceding lossy data-conversion step lossless; the voltage clamping used in the bit-packed representation is discussed separately in the experimental method.
The theoretical background below is intentionally limited to properties needed to interpret the experiments: dictionary/window size, parameterisation, token structure, computational effort, and working-memory demand.
3.1 LZW
Lempel–Ziv–Welch (LZW) builds a dictionary of substrings while it processes the input. An initial alphabet occupies the first codes; whenever the encoder emits the code for the longest dictionary match, it adds that match followed by the next byte as a new entry. The decoder builds the same dictionary from the received codes, so no dictionary is transmitted separately (Sahu and Panda, 2023; Sharma, 2020; David Bryant, n.d.; The Wuffs Authors, n.d.; Mark, 1989).
The maximum code width controls the number of dictionary entries and therefore the principal trade-off examined here. A width of b bits permits up to 2*b* codes; increasing b can represent more repeated substrings but causes dictionary RAM to grow approximately exponentially. Codes may be stored in fixed-width words or packed bitwise. Bit packing avoids unused high bits, but adds packing/unpacking work. Once the dictionary is full, an implementation must freeze or reset it in a manner reproduced by the decoder. LZW is consequently most effective on structured inputs with recurring substrings and can expand inputs with little redundancy.
3.2 LZSS background
Lempel–Ziv–Storer–Szymanski (LZSS), a refinement of LZ77, represents repeated input either as literal bytes or as back-references containing an offset and a match length (Wiseman, 2007; Free Software Foundation and Jean-loup Gailly, 2025). A history window bounds how far the encoder can search backwards; the maximum match length bounds how much data one reference can reproduce. Larger bounds can improve compression but require more state and may increase search time. Implementations use hash tables, trees, or other indexes to avoid exhaustive searches.
LZSS is included as conceptual background because Heatshrink, LZ4, FastLZ, and the dictionary stage of DEFLATE all use variants of this literal/back-reference principle. They differ in window size, match finding, token encoding, entropy coding, and memory allocation, which explains why their experimental trade-offs differ.
3.3 Heatshrink
Heatshrink is an LZSS-style compressor designed for small embedded systems (Atomic Object, n.d.). Its two compile-time parameters are the window size exponent N and look-ahead exponent M. The history capacity is 2*N* bytes and the maximum encoded match is governed by 2*M*, with M<N. A larger window exposes more previous data to matching, whereas a larger look-ahead permits longer matches. Both can improve compressed size on repetitive data but increase working memory and search work.
Heatshrink emits bit-packed literal or back-reference tokens. This compact token representation and configurable buffers can provide low algorithm working memory, but match searching can be slower than the hash-oriented strategies used by LZ4 and FastLZ. The experiments therefore vary N and M separately to expose the compression–time–memory trade-off.
3.4 LZ4
LZ4 uses a 64-KiB history distance and hash-based match finding. Each sequence contains a token, a run of literals, a two-byte offset, and a match; extension bytes represent literal or match lengths that exceed the token fields (Liu and Song, 2026; Jiang and Lin, 2020; LZ4 Project Developers, n.d.; LZ4 Project, n.d.). The simple byte-aligned format and limited candidate search reduce branches and parsing overhead, favoring high speed over maximum compression.
The tested LZ4_compress_fast() interface exposes an acceleration parameter. Higher values skip more candidate positions and normally reduce compression time at the cost of a larger output. The hash table and input/output buffers dominate static RAM in the tested firmware; consequently, the memory figures must be compared only after common buffers are included consistently for every algorithm.
3.5 FastLZ
FastLZ is an ANSI C implementation of an LZ77-style byte-stream compressor designed for rapid compression and decompression (Ariya Hidayat, n.d.). It uses three-byte hashing to locate a recent candidate and emits runs of literals or offset/length matches. Level 1 favors short matches and speed, whereas level 2 supports a more extensive match representation intended to improve compression on larger inputs. These are the two modes provided by the library and therefore the two settings evaluated in this study.
FastLZ avoids entropy coding and uses a comparatively simple control format. This limits processing overhead, but the result depends strongly on whether its recent hash candidate captures the repeated structures in a dataset. Unsupported universal throughput and compression-ratio comparisons with LZ4 are not assumed; performance is reported only for the common STM32 platform and dataset used in this study.
3.6 Miniz
Miniz implements DEFLATE, which combines LZ77-style length/distance references with Huffman entropy coding (Rich Geldreich, n.d.; Tu and Puchala, 2022). DEFLATE operates with a 32-KiB sliding window and encodes blocks as stored, fixed-Huffman, or dynamic-Huffman blocks. Dynamic blocks transmit code-length information but can assign shorter codes to frequent literals and match symbols, often producing smaller outputs when the gain exceeds the header overhead.
Miniz compression levels alter the effort devoted to match search and block construction. Higher effort can improve compressed size but can also increase execution time, while the 32-KiB dictionary and encoder state make its working-memory requirement larger than those of simpler embedded-oriented formats. In the present dataset, levels 1–9 produced almost identical output sizes, showing that increased search effort did not yield additional compression for these inputs.
4 Compression algorithms evaluation on text and binary files
4.1 Microcontroller
The evaluation of different compression algorithms was performed on the STM NUCLEO-U575ZI-Q development board, which contains the STM32U575ZI microcontroller with the following properties:
- CPU: Arm Cortex-M33 with maximal system clock of 160, MHz, single-precision FPU, and DSP instructions.
- Memory: 2 MB of Flash and 786 KB of SRAM.
- Power: supply voltage range 1.7 V to 3.6 V; multiple low-power modes and ultra-low-power design.
- Typical applications: secure IoT nodes, industrial controllers, smart meters, audio and multimedia devices, and Ethernet-enabled embedded systems.
The microcontroller firmware was written in C using STM32CubeMX v6.17.0 and STM32CubeIDE v2.1.1 (STMicroelectronics, Geneva, Switzerland). During tests, the microcontroller ran at a 160 MHz system clock and was powered from 3.3 V.
STM32CubeIDE used during experiments the following settings:
- Toolchain: GNU Tools for STM32 (14.3.rel1).
- Assembler: GNU assembler (arm-none-eabi-as).
- Compiler: GNU Arm Embedded Toolchain (arm-none-eabi-gcc).
- Linker: GNU linker (arm-none-eabi-ld).
- Compiler optimization level: None (–O0).
- Compiler debug level: Maximum (–g3).
- Compiler language standard: GNU11 (ISO C11 + GNU extensions) (-std=gnu11).
Compressed output size is deterministic for a fixed input, library version, and parameter setting. Static RAM was obtained from the linker allocation and maximum stack usage from the stack measurement in the benchmarking firmware; these quantities are therefore reported without dispersion statistics. Compression and decompression time were measured with the Arm Cortex–M33 DWT cycle counter (DWT->CYCCNT) while the processor ran at 160 MHz, giving a nominal resolution of 6.25 ns; cycle counts were converted to milliseconds and microseconds. The published tables contain one recorded timing value per configuration. Although repeated executions were used during development to check repeatability, the number of runs and individual run-level timings were not retained. Consequently, means and standard deviations cannot be reconstructed. All timing comparisons in this article are therefore descriptive comparisons of the recorded values; no inferential statistical significance is claimed.
4.2 CSV file
For compression algorithm evaluation, we used a dataset containing environmental data in CSV format with a size of 104,067 bytes.
C source files (.c and .h) are compiled to object files (.o) and linked into an executable (.elf or .bin). To embed a CSV file into STM32 firmware, the CSV was converted into an object file using the ARM toolchain bundled with STM32CubeIDE.
The dataset was gathered during another research project at our department. The CSV file has the following headers:
- created_at (25 bytes): timestamp (ISO 8601) when the entry was recorded (example: 2025-11-05T09:30:45+00:00).
- entry_id (1–4 bytes): identification number of the entry in the CSV file, ranging from 0 to 1399 (total number of entries in the used CSV file).
- field1 (3–6 bytes): soil temperature at 80 cm depth (example: 5.6 or –15.25).
- field2 (3–6 bytes): soil temperature at 65 cm depth.
- field3 (3–6 bytes): soil temperature at 50 cm depth.
- field4 (3–6 bytes): soil temperature at 35 cm depth.
- field5 (3–6 bytes): soil temperature at 20 cm depth.
- field6 (3–6 bytes): ambient temperature.
- field7 (3–5 bytes): ambient humidity (example: 63.55).
- field8 (3–4 bytes): battery voltage of the WSN measurement node (example: 3.7).
- latitude (0 bytes): empty field.
- longitude (0 bytes): empty field.
- elevation (0 bytes): empty field.
- status (0 bytes): empty field.
Note: The CSV contains 14 columns in total (the 14 headers listed above); therefore, each line contains additional 13 comma separators.
The original CSV can be further pre-processed to reduce its size before applying compression algorithms; this preprocessing is described later in the document.
4.2.1 Compression ratio
In all the following tables, the compression ratio is calculated using the Equation 1:
compression ratio (%)=size of compressed datasize of original data·100(1)
- When the compression ratio is below 100%, the compressed file is smaller than the original file.
- When the compression ratio is 100%, the compressed and original files have the same size.
- When the compression ratio is above 100%, the compressed file is larger than the original file.
4.3 Compression algorithms evaluation on a CSV file
During evaluation, we used the following C libraries:
- LZW—https://github.com/dbry/lzw-ab/tree/master (David Bryant, n.d.)
- Heatshrink—https://github.com/atomicobject/heatshrink (Atomic Object, n.d.)
- LZ4—https://github.com/lz4/lz4 (LZ4 Project Developers, n.d.)
- FastLZ—https://github.com/ariya/FastLZ (Ariya Hidayat, n.d.)
- Miniz—https://github.com/richgel999/miniz (Rich Geldreich, n.d.)
Parameter ranges were selected to exercise the trade-offs exposed by each library rather than applying one arbitrary range to every algorithm. LZW code widths 9–16 cover the complete range accepted by the implementation and vary dictionary capacity from 29 to 216 entries. Heatshrink tests separately vary window bits (history capacity) and look-ahead bits (maximum match), while respecting the library constraint that look-ahead bits are smaller than window bits. LZ4 acceleration values 1–16 form a practical sweep from the library's default high-compression search effort toward progressively faster candidate skipping. FastLZ levels 1 and 2 are the only two modes defined by that library. Miniz levels 1–9 cover its standard compression-level range from fastest to maximum search effort.
All compression algorithms were evaluated using statically allocated compression and decompression buffers placed in static RAM. The size of each buffer was 110 KiB (112,640 bytes), for a common buffer allocation of 225,280 bytes. The detailed per-algorithm tables reproduce the raw implementation measurements; because some integrations included the common buffers in the linker total whereas LZW and Heatshrink reported only algorithm working memory, those raw columns must not be compared across algorithms. Table 2 provides the normalized cross-algorithm comparison by including both common buffers, algorithm static memory, and maximum stack for every implementation. Buffer size can be modified by changing the corresponding macro in the memory_requirements file located in the compression_data folder in the git repository.
Table 2. Normalized total application RAM (common buffers + algorithm static memory + maximum stack) for runs with the smallest compressed output.
| Compression algorithm | CSV file | Binary file | Bit-packed binary file |
|---|---|---|---|
| LZW | 246,172 | 74,652 | 60,316 |
| LZW bit-packed | 230,812 | 74,652 | 60,316 |
| Heatshrink | 238,596 | 73,092 | 58,740 |
| LZ4 | 226,761 | 72,860 | 58,496 |
| FastLZ | 231,952 | 74,512 | 59,817 |
| Miniz | 274,496 | 113,216 | 98,163 |
4.3.1 LZW
The LZW library allows setting the maximal code width in the range 9 to 16 bits. The results of compression evaluation on the CSV file are shown in Table 3.
Table 3. LZW compression and decompression evaluation on the CSV file.
| Length of codes | Compressed output size in bytes (16-bit storage) | Compressed output size in bytes (bit-packed) | Compression ratio (%, 16-bit storage) | Compression ratio (%, bit-packed) | Compression time (ms:μs) | Decompression time (ms:μs) | Static RAM usage (bytes) |
|---|---|---|---|---|---|---|---|
| 9 | 65,274 | 36,717 | 62.72 | 35.28 | 175 ms 645 μs | 129 ms 1 μs | 2,560 |
| 10 | 54,156 | 33,848 | 52.03 | 32.52 | 168 ms 168 μs | 113 ms 403 μs | 5,120 |
| 11 | 49,706 | 34,173 | 47.76 | 32.83 | 164 ms 284 μs | 104 ms 41 μs | 10,240 |
| 12 | 48,638 | 36,479 | 46.73 | 35.05 | 163 ms 278 μs | 97 ms 907 μs | 20,480 |
| 13 | 48,958 | 39,779 | 47.04 | 38.22 | 161 ms 601 μs | 93 ms 376 μs | 40,960 |
| 14 | 49,530 | 43,339 | 47.59 | 41.64 | 156 ms 765 μs | 87 ms 482 μs | 81,920 |
For 15- and 16-bit code compression, the run failed.
- Best compression ratio when codes are stored as 16-bit words was achieved with 12-bit codes (46.73%) with an output size of 48,638 bytes.
- Best compression ratio when codes are bit-packed was achieved with 10-bit codes (32.52%) with an output size of 33,848 bytes.
- The fastest compression time (156 ms 765 μs) and decompression time (87 ms 482 μs) were observed with 14-bit codes.
- Static memory consumption increases approximately exponentially with code width because LZW dictionary capacity grows as 2bits. In these tests, static usage rose from 2.5 KiB (2,560 bytes) for 9-bit codes to 80 KiB (81,920 bytes) for 14-bit codes.
- Maximum stack usage during compression and decompression remained nearly constant (about 404 to 412 bytes).
- Increasing code width primarily affects static RAM (allocated at link time) that holds the dictionary and related structures; stack usage (runtime allocation) is largely unaffected. Consequently, LZW memory requirements are dominated by the number of bits used to store codes.
4.3.2 Heatshrink
The Heatshrink library allows setting window bits in the range 4–15 and lookahead bits in the range 3 to (window bits − 1). In all tests, the input buffer size was set to 32 KiB and the index table was enabled for faster compression.
The window bits and lookahead bits are configured in heatshrink_config in the heatshrink_compression folder.
In the first set of tests, lookahead bits were fixed at 5 (maximum match length 32 bytes), and window bits were varied from 6 to 13. The results of compression evaluation on the CSV file are shown in Table 4.
- Best compression ratio (20.91%) was achieved with 12 window bits with an output size of 21,764 bytes.
- The fastest compression time (282 ms 0 μs) was observed with 8 window bits. The fastest decompression time (139 ms 199 μs) was observed with 13 window bits.
- Compression ratio decreases as window bits increase up to 12, after which it starts to increase.
- Compression time increases with window size; this is expected because larger windows require more time to search for matches.
- Decompression time remains nearly constant (except for 6 window bits) as window size changes.
- Static RAM usage grows with window bits because the history window and index table are statically allocated at the start of the Heatshrink algorithm.
- Maximum stack usage during compression and decompression remained nearly constant (compression: 820 –836 bytes; decompression: 396–400 bytes).
Table 4. Heatshrink compression and decompression evaluation with lookahead bits set to 5 on the CSV file.
| Window bits | Sliding window size (bytes) | Compressed output size (bytes) | Compression ratio (%) | Compression time (ms:μs) | Decompression time (ms:μs) | Static RAM usage (bytes) |
|---|---|---|---|---|---|---|
| 6 | 64 | 89,954 | 86.43 | 805 ms 816 μs | 396 ms 165 μs | 384 |
| 7 | 128 | 25,453 | 24.45 | 298 ms 656 μs | 155 ms 72 μs | 576 |
| 8 | 256 | 23,084 | 22.18 | 282 ms 0 μs | 144 ms 310 μs | 960 |
| 9 | 512 | 22,407 | 21.53 | 317 ms 722 μs | 146 ms 870 μs | 1,728 |
| 10 | 1,024 | 22,015 | 21.15 | 403 ms 869 μs | 140 ms 925 μs | 3,264 |
| 11 | 2,048 | 21,840 | 20.98 | 549 ms 322 μs | 139 ms 821 μs | 6,336 |
| 12 | 4,096 | 21,764 | 20.91 | 812 ms 175 μs | 139 ms 241 μs | 12,480 |
| 13 | 8,192 | 21,999 | 21.13 | 1 s 281 ms 318 μs | 139 ms 199 μs | 24,768 |
In the second set of tests, window bits were fixed at 12, and lookahead bits were varied from 3 to 11. The results are shown in Table 5.
- Best compression ratio (20.91%) was achieved with 5 lookahead bits with an output size of 21,764 bytes.
- The fastest compression time (791 ms 637 μs) was achieved with 8 lookahead bits. The fastest decompression time (139 ms 241 μs) was achieved with 5 lookahead bits.
- Using lookahead bits larger than 5 generally worsens the compression ratio and increases compression/decompression time.
- Static RAM usage increases with lookahead bits approximately as 2lookahead bits − 1 due to static allocation of the lookahead buffer at initialization.
- Maximum stack usage during compression and decompression remained nearly constant (compression: 820–824 bytes; decompression: 396–404 bytes).
Table 5. Heatshrink compression and decompression evaluation with window bits set to 12 on the CSV file.
| Lookahead bits | Maximum match length (bytes) | Compressed output size (bytes) | Compression ratio (%) | Compression time (ms:μs) | Decompression time (ms:μs) | Static RAM usage (bytes) |
|---|---|---|---|---|---|---|
| 3 | 8 | 33,484 | 32.17 | 870 ms 16 μs | 191 ms 923 μs | 12,456 |
| 4 | 16 | 24,049 | 23.10 | 816 ms 858 μs | 150 ms 339 μs | 12,464 |
| 5 | 32 | 21,764 | 20.91 | 812 ms 175 μs | 139 ms 241 μs | 12,480 |
| 6 | 64 | 22,407 | 21.53 | 816 ms 134 μs | 140 ms 151 μs | 12,512 |
| 7 | 128 | 23,461 | 22.54 | 820 ms 1 μs | 142 ms 699 μs | 12,576 |
| 8 | 256 | 24,514 | 23.55 | 791 ms 637 μs | 145 ms 266 μs | 12,704 |
| 9 | 512 | 25,567 | 24.56 | 807 ms 552 μs | 153 ms 261 μs | 12,960 |
| 10 | 1,024 | 26,620 | 25.57 | 821 ms 309 μs | 155 ms 810 μs | 13,472 |
| 11 | 2,048 | 26,900 | 25.84 | 964 ms 680 μs | 154 ms 160 μs | 14,496 |
4.3.3 LZ4
Compression was performed with LZ4_compress_fast(), varying the acceleration parameter from 1 to 16. Higher acceleration generally trades compression effectiveness for speed; under the ratio definition used here, this means that a faster setting can produce a larger compressed-to-input size ratio. Decompression used LZ4_decompress_safe(). Results of compression evaluation on the CSV file are shown in Table 6.
- Best compression ratio (30.94%) with an output size of 32,207 bytes was observed with acceleration= 1.
- The fastest compression time (66 ms 805 μs) and decompression time (14 ms 658 μs) were observed with acceleration= 16.
- Static RAM usage remained constant at 225,737 bytes (220.5 KiB) across all tested acceleration values.
- LZ4 showed substantially lower recorded compression and decompression times than Heatshrink, whereas Heatshrink achieved a smaller compressed-to-input size ratio. Raw static-RAM figures are not compared across implementations; normalized total application RAM is compared separately in Table 2.
- Variations in compression ratio and timing across acceleration values are relatively small.
- Maximum stack usage during compression and decompression remained constant (compression: 1024 bytes; decompression: 436 bytes).
Table 6. LZ4 compression and decompression evaluation on the CSV file.
| Acceleration | Compressed output size (bytes) | Compression ratio (%) | Compression time (ms:μs) | Decompression time (ms:μs) | Static RAM usage (bytes) |
|---|---|---|---|---|---|
| 1 | 32,207 | 30.94 | 69 ms 619 μs | 15 ms 79 μs | 225,737 |
| 2 | 32,451 | 31.18 | 69 ms 510 μs | 15 ms 41 μs | 225,737 |
| 3 | 32,471 | 31.20 | 69 ms 87 μs | 14 ms 979 μs | 225,737 |
| 4 | 32,664 | 31.38 | 69 ms 110 μs | 14 ms 971 μs | 225,737 |
| 5 | 32,905 | 31.61 | 68 ms 811 μs | 14 ms 927 μs | 225,737 |
| 6 | 32,865 | 31.58 | 68 ms 803 μs | 14 ms 913 μs | 225,737 |
| 7 | 33,036 | 31.74 | 68 ms 679 μs | 14 ms 892 μs | 225,737 |
| 8 | 33,328 | 32.02 | 68 ms 556 μs | 14 ms 833 μs | 225,737 |
| 9 | 33,796 | 32.47 | 68 ms 230 μs | 14 ms 813 μs | 225,737 |
| 10 | 33,966 | 32.63 | 68 ms 6 μs | 14 ms 777 μs | 225,737 |
| 11 | 34,371 | 33.02 | 67 ms 663 μs | 14 ms 718 μs | 225,737 |
| 12 | 34,572 | 33.22 | 67 ms 315 μs | 14 ms 668 μs | 225,737 |
| 13 | 34,642 | 33.28 | 67 ms 254 μs | 14 ms 749 μs | 225,737 |
| 14 | 34,583 | 33.23 | 67 ms 52 μs | 14 ms 744 μs | 225,737 |
| 15 | 34,937 | 33.57 | 66 ms 996 μs | 14 ms 711 μs | 225,737 |
| 16 | 35,014 | 33.64 | 66 ms 805 μs | 14 ms 658 μs | 225,737 |
4.3.4 FastLZ
FastLZ was evaluated at compression levels 1 and 2. The results of the compression evaluation on the CSV file are shown in Table 7.
- Level 1 produced the best compression ratio (27.19%), with an output size of 28,303 bytes, and the shortest compression (61 ms 401 μs) and decompression (14 ms 279 μs) times.
- Maximum stack usage remained constant (compression: 1,024 bytes; decompression: 340 bytes).
Table 7. FastLZ compression and decompression evaluation on the CSV file.
| Level | Compressed output size (bytes) | Compression ratio (%) | Compression time (ms:μs) | Decompression time (ms:μs) | Static RAM usage (bytes) |
|---|---|---|---|---|---|
| 1 | 28,303 | 27.19 | 61 ms 401 μs | 14 ms 279 μs | 230,928 |
| 2 | 28,416 | 27.30 | 62 ms 8 μs | 15 ms 169 μs | 230,928 |
4.3.5 Miniz
Miniz was evaluated at compression levels 1–9. The results of compression evaluation on the CSV file are shown in Table 8.
- All evaluated levels produced essentially the same compressed size (best output: 16,029 bytes), compression ratio (15.40%), and static RAM usage (273,472 bytes, or 267 KiB). Thus, increasing the Miniz level had a negligible effect on compressed size for this dataset.
- The fastest compression time (761 ms 425 μs) was observed at level 1. The fastest decompression time (21 ms 992 μs) was observed at levels 4 to 9.
- Maximum stack usage remained constant (compression: 856 bytes; decompression: 1024 bytes).
- Miniz achieved the smallest compressed output among the evaluated algorithms, but the corresponding minimum-output configuration also had the largest normalized total application RAM and a relatively long compression time.
Table 8. Miniz compression and decompression evaluation on the CSV file.
| Level | Compressed output size (bytes) | Compression ratio (%) | Compression time (ms:μs) | Decompression time (ms:μs) | Static RAM usage (bytes) |
|---|---|---|---|---|---|
| 1 | 16,036 | 15.40 | 761 ms 425 μs | 22 ms 0 μs | 273,472 |
| 2 | 16,029 | 15.40 | 887 ms 439 μs | 21 ms 993 μs | 273,472 |
| 3 | 16,032 | 15.40 | 941 ms 467 μs | 21 ms 995 μs | 273,472 |
| 4 | 16,033 | 15.40 | 959 ms 36 μs | 21 ms 992 μs | 273,472 |
| 5 | 16,033 | 15.40 | 961 ms 763 μs | 21 ms 992 μs | 273,472 |
| 6 | 16,033 | 15.40 | 963 ms 665 μs | 21 ms 992 μs | 273,472 |
| 7 | 16,033 | 15.40 | 964 ms 911 μs | 21 ms 992 μs | 273,472 |
| 8 | 16,033 | 15.40 | 965 ms 424 μs | 21 ms 992 μs | 273,472 |
| 9 | 16,033 | 15.40 | 965 ms 834 μs | 21 ms 992 μs | 273,472 |
4.4 Binary file
The original dataset can be pre-processed (stored in a different format) to reduce its size before applying compression algorithms. The size of a file is determined by the number of bytes it occupies in memory. Each byte contains 8 bits; each bit b*i* can be set to either logical one or logical zero. Therefore, byte can be written as shown in Equation 2:
byte=[b7b6b5b4b3b2b1b0](2)
A byte can store values from 0b0000_0000 (0 in decimal) to 0b1111_1111 (255 in decimal).
Text files (to which CSV files belong) store data in text format, in which every character (letter, number, dot, dash, etc.) is associated, through an ASCII table (or compatible encodings such as UTF-8), with a number that represents it in memory. For example, in the ASCII table, letter A is represented by decimal value 65 (0b0100_0001). With the basic ASCII table, each character occupies one byte; therefore, the size of the text file is equal to the number of characters it contains. Storing data in text format is a suitable choice when the original data contains a mix of characters.
Binary files store data in binary format, which allows numerical values to be stored in a more space-efficient manner. For example, number 156 is stored in text format using three bytes (one byte per digit). However, in binary format, the same number can be stored in a single byte by setting individual bits; that is, number 156 is represented in binary as 0b1001_1100.
Storing numerical data in a binary file instead of a text file (CSV file), therefore, represents an effective approach to reducing file size prior to compression.
During the following series of tests, binary files with the format described below were used:
- The timestamp (ISO 8601), for example 2025-11-05T09:30:45+00:00, which occupied 25 bytes in the CSV file, was converted into 6 bytes representing year, month, day, hour, minute, and second (e.g., 25 11 5 9 30 45, where the year is stored as an offset from 2000). The time-zone offset was removed because it was always +00:00 in the original dataset.
- The entry ID, which occupied 1 to 4 bytes in the CSV file, was converted to 2 bytes, allowing entry IDs in the range 0 to 65,535.
- Fields field1 to field8, each occupying 3 to 6 bytes in the CSV file, were converted to 2 bytes each. The integer part of the number is represented by one signed byte (range -128 to +127), while the fractional part (up to two decimal places), multiplied by 100 (range 0–99), is stored in a second unsigned byte.
- The latitude, longitude, elevation, and status fields were omitted because they were empty in the original CSV file.
In the original CSV file, each entry (line) occupied between 63 and 87 bytes. In a binary file, each entry occupies exactly 24 bytes. With this approach, the file size is substantially reduced compared with the CSV representation, while simultaneously enabling deterministic processing on the microcontroller side without the need to parse delimiter characters (commas in CSV), since each entry component occupies a fixed number of bytes in a binary file.
Using the described binary format, the size of the original CSV file was reduced from 104,067 bytes to 33,576 bytes. This corresponds to a size reduction to 32.26% of the original file size.
All compression algorithms were tested using statically allocated compression and decompression buffers placed in static RAM. The size of each buffer was 35 KiB (35,840 bytes), for a common buffer allocation of 71,680 bytes. As for the CSV tests, raw detailed RAM columns reflect the integration-specific linker measurement and are not used directly for cross-algorithm ranking. The normalized summary adds the two common buffers, algorithm static memory, and maximum stack consistently. Buffer size can be modified by changing the corresponding macro in the memory_requirements file located in the compression_data folder in the git repository.
4.5 Compression algorithms evaluation on binary file
4.5.1 LZW
The LZW library allows setting the maximal code width in the range of 9 to 16 bits. The results of compression evaluation on the binary file are shown in Table 9.
- Best compression ratio when codes are stored as 16-bit words was achieved with 9-bit codes (85.65%) with output size of 28,758 bytes.
- Best compression ratio when codes are bit-packed was achieved with 9-bit codes (48.18%) with an output size of 16,177 bytes.
- The fastest compression time (61 ms 926 μs) was observed with 9-bit codes. The fastest decompression time (38 ms 861 μs) was observed with 15-bit codes.
- Static memory consumption increases approximately exponentially with code width because LZW dictionary capacity grows as 2bits. In these tests, static usage rose from 2.5 KiB (2 560 bytes) for 9-bit codes to 327 KiB (327,680 bytes) for 16-bit codes.
- Maximum stack usage during compression and decompression remained nearly constant (about 404–412 bytes).
- Increasing code width primarily affects static RAM (allocated at link time) that holds the dictionary and related structures; stack usage (runtime allocation) is largely unaffected. Consequently, LZW memory requirements are dominated by the number of bits used to store codes.
Table 9. LZW compression and decompression evaluation on the binary file.
| Length of codes | Compressed output size in bytes (16-bit storage) | Compressed output size in bytes (bit-packed) | Compression ratio (%, 16-bit storage) | Compression ratio (%, bit-packed) | Compression time (ms:μs) | Decompression time (ms:μs) | Static RAM usage (bytes) |
|---|---|---|---|---|---|---|---|
| 9 | 28,758 | 16,177 | 85.65 | 48.18 | 61 ms 926 μs | 47 ms 791 μs | 2,560 |
| 10 | 30,102 | 18,814 | 89.65 | 56.03 | 66 ms 218 μs | 46 ms 128 μs | 5,120 |
| 11 | 31,404 | 21,591 | 93.53 | 64.30 | 72 ms 644 μs | 44 ms 962 μs | 10,240 |
| 12 | 32,354 | 24,266 | 96.36 | 72.27 | 80 ms 863 μs | 42 ms 784 μs | 20,480 |
| 13 | 32,610 | 26,496 | 97.12 | 78.91 | 86 ms 314 μs | 40 ms 421 μs | 40,960 |
| 14 | 32,786 | 28,688 | 97.64 | 85.44 | 85 ms 933 μs | 38 ms 862 μs | 81,920 |
| 15 | 32,786 | 30,737 | 97.64 | 91.54 | 85 ms 933 μs | 38 ms 861 μs | 163,840 |
| 16 | 32,786 | 32,786 | 97.64 | 97.64 | 85 ms 934 μs | 38 ms 862 μs | 327,680 |
4.5.2 Heatshrink
The Heatshrink library allows setting window bits in the range 4–15 and lookahead bits in the range 3 to (window bits − 1). In all tests, the input buffer size was set to 32 KiB and the index table was enabled for faster compression.
The window bits and lookahead bits are configured in heatshrink_config in the heatshrink_compression folder.
In the first set of tests, lookahead bits were fixed at 5 (maximum match length 32 bytes), and window bits were varied from 6 to 13. The results of compression evaluation on the binary file are shown in Table 10.
- Best compression ratio (39.31%) was achieved with 7 window bits with output size of 13,200 bytes.
- The fastest compression time (121 ms 84 μs) and decompression time (66 ms 953 μs) were observed with 8 window bits.
- Compression time increases with window size; this is expected because larger windows require more time to search for matches.
- Decompression time remains nearly constant as window size changes.
- Static RAM usage grows with window bits because the history window and index table are statically allocated at the start of the Heatshrink algorithm.
- Maximum stack usage during compression and decompression remained constant (compression: 820 bytes; decompression: 396 bytes).
Table 10. Heatshrink compression and decompression evaluation with lookahead bits set to 5 on the binary file.
| Window bits | Sliding window size (bytes) | Compressed output size (bytes) | Compression ratio (%) | Compression time (ms:μs) | Decompression time (ms:μs) | Static RAM usage (bytes) |
|---|---|---|---|---|---|---|
| 6 | 64 | 14,082 | 41.94 | 147 ms 71 μs | 70 ms 713 μs | 384 |
| 7 | 128 | 13,200 | 39.31 | 121 ms 975 μs | 67 ms 62 μs | 576 |
| 8 | 256 | 13,281 | 39.55 | 121 ms 84 μs | 66 ms 953 μs | 960 |
| 9 | 512 | 13,572 | 40.42 | 136 ms 462 μs | 69 ms 911 μs | 1,728 |
| 10 | 1,024 | 13,775 | 41.02 | 166 ms 542 μs | 69 ms 298 μs | 3,264 |
| 11 | 2,048 | 14,115 | 42.03 | 231 ms 840 μs | 70 ms 116 μs | 6,336 |
| 12 | 4,096 | 14,442 | 43.01 | 386 ms 721 μs | 70 ms 975 μs | 12,480 |
| 13 | 8,192 | 14,804 | 44.09 | 772 ms 792 μs | 71 ms 913 μs | 24,768 |
In the second set of tests, window bits were fixed at 7, and lookahead bits were varied from 3 to 7. Results are shown in Table 11.
- Best compression ratio (38.58%) was achieved with 4 lookahead bits with an output size of 12,954 bytes.
- The shortest compression (117 ms 291 μs) and decompression (66 ms 829 μs) times were achieved with 4 look-ahead bits.
- Using lookahead bits larger than 4 generally worsens the compression ratio and increases compression/decompression time.
- Static RAM usage increases with lookahead bits approximately as 2lookahead bits − 1 due to static allocation of the lookahead buffer at initialization.
- Maximum stack usage during compression and decompression remained nearly constant (compression: 392 to 402 bytes; decompression: 396 to 404 bytes).
Table 11. Heatshrink compression and decompression evaluation with window bits set to 7 on the binary file.
| Lookahead bits | Maximum match length (bytes) | Compressed output size (bytes) | Compression ratio (%) | Compression time (ms:μs) | Decompression time (ms:μs) | Static RAM usage (bytes) |
|---|---|---|---|---|---|---|
| 3 | 8 | 13,898 | 41.39 | 124 ms 866 μs | 72 ms 82 μs | 552 |
| 4 | 16 | 12,954 | 38.58 | 117 ms 291 μs | 66 ms 829 μs | 560 |
| 5 | 32 | 13,200 | 39.31 | 121 ms 975 μs | 67 ms 62 μs | 576 |
| 6 | 64 | 13,625 | 40.57 | 136 ms 66 μs | 68 ms 89 μs | 608 |
| 7 | 128 | 14,050 | 41.84 | 1 s 53 ms 586 μs | 69 ms 120 μs | 672 |
4.5.3 LZ4
Compression was performed with LZ4_compress_fast(), varying the acceleration parameter from 1 to 16. Higher acceleration generally trades compression effectiveness for speed; under the ratio definition used here, this means that a faster setting can produce a larger compressed-to-input size ratio. Decompression used LZ4_decompress_safe(). Results of compression evaluation on the binary file are shown in Table 12.
- Best compression ratio (53.63%) with output size of 18,009 bytes was observed with acceleration= 1.
- The shortest compression (13 ms 399 μs) and decompression (1 ms 587 μs) times were observed with acceleration = 12.
- Static RAM usage remained constant at 71,836 bytes across all tested acceleration values.
- LZ4 showed substantially lower recorded compression and decompression times than Heatshrink, whereas Heatshrink achieved a smaller compressed-to-input size ratio. Raw static-RAM figures are not compared across implementations; normalized total application RAM is compared separately in Table 2.
- Maximum stack usage during compression and decompression remained nearly constant (compression: 1,024 bytes; decompression: 476–516 bytes).
Table 12. LZ4 compression and decompression evaluation on the binary file.
| Acceleration | Compressed output size (bytes) | Compression ratio (%) | Compression time (ms:μs) | Decompression time (ms:μs) | Static RAM usage (bytes) |
|---|---|---|---|---|---|
| 1 | 18,009 | 53.63 | 42 ms 542 μs | 4 ms 979 μs | 71,836 |
| 2 | 18,255 | 54.36 | 39 ms 875 μs | 4 ms 874 μs | 71,836 |
| 3 | 18,574 | 55.31 | 38 ms 781 μs | 4 ms 727 μs | 71,836 |
| 4 | 19,049 | 56.73 | 37 ms 652 μs | 4 ms 512 μs | 71,836 |
| 5 | 19,586 | 58.33 | 35 ms 730 μs | 4 ms 223 μs | 71,836 |
| 6 | 20,750 | 61.80 | 33 ms 510 μs | 3 ms 982 μs | 71,836 |
| 7 | 21,730 | 64.71 | 31 ms 789 μs | 3 ms 837 μs | 71,836 |
| 8 | 22,179 | 66.05 | 30 ms 865 μs | 3 ms 820 μs | 71,836 |
| 9 | 23,605 | 70.30 | 28 ms 564 μs | 3 ms 559 μs | 71,836 |
| 10 | 25,636 | 76.35 | 24 ms 544 μs | 3 ms 229 μs | 71,836 |
| 11 | 28,159 | 83.86 | 19 ms 640 μs | 2 ms 609 μs | 71,836 |
| 12 | 29,898 | 89.04 | 13 ms 399 μs | 1 ms 587 μs | 71,836 |
| 13 | 27,564 | 82.09 | 20 ms 94 μs | 3 ms 54 μs | 71,836 |
| 14 | 27,632 | 82.29 | 20 ms 461 μs | 3 ms 225 μs | 71,836 |
| 15 | 28,431 | 84.67 | 19 ms 305 μs | 3 ms 80 μs | 71,836 |
| 16 | 28,918 | 86.12 | 19 ms 774 μs | 3 ms 324 μs | 71,836 |
4.5.4 FastLZ
FastLZ was evaluated at compression levels 1 and 2. The results of the compression evaluation on the binary file are shown in Table 13.
- Level 1 produced the best compression ratio (52.39%) with an output size of 17,591 bytes and the fastest compression (31 ms 653 μs) and decompression (6 ms 78 μs) times.
- Maximum stack usage remained constant (compression: 1,024 bytes; decompression: 340 bytes).
Table 13. FastLZ compression and decompression evaluation on the binary file.
| Level | Compressed output size (bytes) | Compression ratio (%) | Compression time (ms:μs) | Decompression time (ms:μs) | Static RAM usage (bytes) |
|---|---|---|---|---|---|
| 1 | 17,591 | 52.39 | 31 ms 653 μs | 6 ms 78 μs | 73,488 |
| 2 | 17,602 | 52.42 | 32 ms 998 μs | 6 ms 759 μs | 73,488 |
4.5.5 Miniz
Miniz was evaluated at compression levels 1–9. The results of compression evaluation on a binary file are shown in Table 14.
- Level 1 produced the best compression ratio (33.81%), with an output size of 11,352 bytes; static RAM usage was identical (112,192 bytes) across all levels. Increasing the Miniz level therefore had a negligible effect on compressed size for this dataset.
- The fastest compression time (219 ms 512 μs) was observed at level 1. The fastest decompression time (12 ms 229 μs) was observed at level 4.
- Maximum stack usage remained constant (compression: 1024 bytes; decompression: 1,024 bytes).
- Miniz achieved the smallest compressed output among the evaluated algorithms, but the corresponding minimum-output configuration also had the largest normalized total application RAM and a relatively long compression time.
Table 14. Miniz compression and decompression evaluation on the binary file.
| Level | Compressed output size (bytes) | Compression ratio (%) | Compression time (ms:μs) | Decompression time (ms:μs) | Static RAM usage (bytes) |
|---|---|---|---|---|---|
| 1 | 11,352 | 33.81 | 219 ms 512 μs | 12 ms 233 μs | 112,192 |
| 2 | 11,358 | 33.82 | 232 ms 498 μs | 12 ms 230 μs | 112,192 |
| 3 | 11,358 | 33.82 | 232 ms 606 μs | 12 ms 230 μs | 112,192 |
| 4 | 11,358 | 33.82 | 232 ms 606 μs | 12 ms 229 μs | 112,192 |
| 5 | 11,358 | 33.82 | 232 ms 605 μs | 12 ms 230 μs | 112,192 |
| 6 | 11,358 | 33.82 | 232 ms 606 μs | 12 ms 230 μs | 112,192 |
| 7 | 11,358 | 33.82 | 232 ms 606 μs | 12 ms 229 μs | 112,192 |
| 8 | 11,358 | 33.82 | 232 ms 605 μs | 12 ms 230 μs | 112,192 |
| 9 | 11,358 | 33.82 | 232 ms 605 μs | 12 ms 230 μs | 112,192 |
4.6 Bit-packed binary file
In the previous data preprocessing iteration, we stored numerical values from the original CSV file (text file) in binary format. By doing so, we reduced the file size from 104,067 bytes to 33,576 bytes. The proposed binary data storage can be further improved, for example, by
- Removing entry index from dataset and calculating it dynamically during data processing.
- Changing the way timestamp (ISO 8601) is stored; instead of storing year, month, day, and hour in each entry, these values could be calculated during processing using stored minutes and seconds.
Both above methods require that the original entry index and original year, month, day, and hour be stored at the beginning of the file, from which all subsequent values can be calculated. Usability of these methods depends heavily on the type of transferred data, and both communicating sides must use the same data preprocessing mechanism to successfully encode and decode data.
In the next preprocessing iteration, we focus on bit-packed data storage in a binary file. So far, each part of the entry has been allocated one or more bytes, meaning that a byte is the smallest unit used. With bit packing, each part of the entry is allocated a specific number of bits, and all bits are subsequently merged.
During the following series of tests, bit-packed binary files were used in the following format:
- The year occupies 2 bits, with a maximum value of 3; the stored value represents an offset from the base year 2025.
- The month occupies 4 bits, with a maximum value of 15, which is sufficient for 12 months.
- The day occupies 5 bits, with a maximum value of 31.
- The hour occupies 5 bits, with a maximum value of 31, which is sufficient for 24 h.
- The minute occupies 6 bits, with a maximum value of 63, which is sufficient for 60 min.
- The second occupies 6 bits, with a maximum value of 63, which is sufficient for 60 s.
- The entry ID occupies 16 bits, with a maximum value of 65,535.
- Fields field1 to field6 use the same bit-packing scheme; both integer and fractional parts occupy 7 bits each. The most significant bit of the integer part represents the sign, resulting in a value range of -64 to 63. The original temperature values do not exceed this interval. The fractional part is stored in the range 0 to 127, which is sufficient because all floating-point values in the original CSV file use a maximum of two decimal places.
- In field7, integer and fractional parts both occupy 7 bits. The integer part does not include the sign bit and has a range of 0 to 127, which is sufficient for humidity measurements in the range 0 to 100.
- In field8, the integer part occupies 3 bits (range 0 to 7), and the fractional part occupies 7 bits. This field represents the voltage of two lithium-ion batteries connected in series that power the WSN node that collected the measurements. The maximum battery voltage when fully charged is 8.4 V (each battery reaches 4.2 V when fully charged). The data preprocessing algorithm clamps all values in field8 that are greater than or equal to 8 to the value 7.99. This preprocessing step results in a loss of precision for voltages above 7.99 V; however, since the application only uses voltage measurements to detect battery discharge (when voltage drops below 7 V), this limitation does not affect the functionality of the final application. The clamping of field8 is a lossy preprocessing step because values above 7.99 V cannot be reconstructed exactly, even though this loss does not affect the intended battery-discharge decision. The subsequent LZW, Heatshrink, LZ4, FastLZ, and Miniz stages remain lossless with respect to the resulting bit-packed byte stream. Accordingly, claims of losslessness in this article refer to compressor input and output, not to equality between the original CSV records and the clamped bit-packed representation.
In the original CSV file, each entry (line) occupied between 63 and 87 bytes. In a binary file, each entry occupies exactly 24 bytes, while in a bit-packed binary file, each entry occupies exactly 19 bytes (152 bits). By using bit packing, the size of the binary file can be further reduced compared to a CSV file, while simultaneously enabling deterministic processing on the microcontroller side without the need to parse delimiter characters (commas in CSV format), since each entry component occupies a fixed number of bits.
Using the described bit-packed binary format, the size of the original CSV file was reduced from 104,067 bytes to 26,581 bytes. This corresponds to preprocessing size reduction to 25.54% of the original CSV file.
All compression algorithms were evaluated using statically allocated compression and decompression buffers placed in static RAM. Each compression and decompression buffer was 28 KiB (28,672 bytes), for a common buffer allocation of 57,344 bytes. The normalized summary includes these buffers, algorithm static memory, and maximum stack for every implementation; the raw detailed RAM columns are retained only to document the measurements of each integration. Buffer size can be adjusted by modifying the corresponding macro in the memory_requirements file located in the compression_data folder in the git repository.
4.7 Compression algorithms evaluation on bit-packed binary file
4.7.1 LZW
The LZW library allows setting the maximal code width in the range 9 to 16 bits. The results of compression evaluation on a bit-packed binary file are shown in Table 15.
- Best compression ratio when codes are stored as 16-bit words was achieved with 9-bit codes (112.77%) with output size of 29,978 bytes. Therefore, storing the LZW codes as 16-bit words results in a compressed output larger than the original bit-packed input.
- Best compression ratio when codes are bit-packed was achieved with 9-bit codes (63.44%) with output size of 16,863 bytes.
- The fastest compression time (54 ms 816 μs) was observed with 9-bit codes. The fastest decompression time (37 ms 212 μs) was observed with 14-bit and 16-bit codes.
- Static memory consumption increases approximately exponentially with code width because LZW dictionary capacity grows as 2bits. In these tests, static usage rose from 2.5 KiB (2,560 bytes) for 9-bit codes to 327 KiB (327,680 bytes) for 16-bit codes.
- Maximum stack usage during compression and decompression remained nearly constant (about 404 to 412 bytes).
- Increasing code width primarily affects static RAM (allocated at link time) that holds the dictionary and related structures; stack usage (runtime allocation) is largely unaffected. Consequently, LZW memory requirements are dominated by the number of bits used to store codes.
Table 15. LZW compression and decompression evaluation on the bit-packed binary file.
| Length of codes | Compressed output size in bytes (16-bit storage) | Compressed output size in bytes (bit-packed) | Compression ratio (%, 16-bit storage) | Compression ratio (%, bit-packed) | Compression time (ms:μs) | Decompression time (ms:μs) | Static RAM usage (bytes) |
|---|---|---|---|---|---|---|---|
| 9 | 29,978 | 16,863 | 112.77 | 63.44 | 54 ms 816 μs | 45 ms 102 μs | 2,560 |
| 10 | 31,676 | 19,798 | 119.16 | 74.48 | 58 ms 663 μs | 43 ms 833 μs | 5,120 |
| 11 | 33,718 | 23,182 | 126.85 | 87.21 | 65 ms 254 μs | 43 ms 045 μs | 10,240 |
| 12 | 35,328 | 26,496 | 132.90 | 99.68 | 75 ms 337 μs | 41 ms 358 μs | 20,480 |
| 13 | 36,192 | 29,406 | 136.15 | 110.62 | 83 ms 434 μs | 39 ms 335 μs | 40,960 |
| 14 | 36,482 | 31,922 | 137.24 | 120.09 | 83 ms 853 μs | 37 ms 212 μs | 81,920 |
| 15 | 36,482 | 34,202 | 137.24 | 128.67 | 83 ms 853 μs | 37 ms 214 μs | 163,840 |
| 16 | 36,482 | 36,482 | 137.24 | 137.24 | 83 ms 853 μs | 37 ms 212 μs | 327,680 |
4.7.2 Heatshrink
The Heatshrink library allows setting window bits in the range 4–15 and lookahead bits in the range 3 to (window bits − 1). In all tests, the input buffer size was set to 32 KiB and the index table was enabled for faster compression.
The window bits and lookahead bits are configured in heatshrink_config in the heatshrink_compression folder.
In the first set of tests, lookahead bits were fixed at 5 (maximum match length 32 bytes) and window bits were varied from 6 to 13. The results of compression evaluation on a bit-packed binary file are shown in Table 16.
- Best compression ratio (54.09%) was achieved with 7 window bits with an output size of 14,378 bytes.
- The fastest compression time (115 ms 338 μs) and decompression time (67 ms 511 μs) were observed with 8 window bits.
- Compression time increases with window size; this is expected because larger windows require more work to search for matches.
- Decompression time remains nearly constant as window size changes.
- Static RAM usage grows with window bits because the history window and index table are statically allocated at the start of the Heatshrink algorithm.
- Maximum stack usage during compression and decompression remained constant (compression: 820 bytes; decompression: 404 bytes).
Table 16. Heatshrink compression and decompression evaluation with lookahead bits set to 5 on the bit-packed binary file.
| Window bits | Sliding window size (bytes) | Compressed output size (bytes) | Compression ratio (%) | Compression time (ms:μs) | Decompression time (ms:μs) | Static RAM usage (bytes) |
|---|---|---|---|---|---|---|
| 6 | 64 | 14,757 | 55.51 | 135 ms 834 μs | 69 ms 185 μs | 384 |
| 7 | 128 | 14,378 | 54.09 | 117 ms 606 μs | 67 ms 578 μs | 576 |
| 8 | 256 | 14,436 | 54.30 | 115 ms 338 μs | 67 ms 511 μs | 960 |
| 9 | 512 | 15,066 | 56.67 | 125 ms 022 μs | 72 ms 793 μs | 1,728 |
| 10 | 1,024 | 15,646 | 58.86 | 141 ms 209 μs | 72 ms 824 μs | 3,264 |
| 11 | 2,048 | 15,996 | 60.17 | 165 ms 726 μs | 73 ms 671 μs | 6,336 |
| 12 | 4,096 | 16,378 | 61.61 | 218 ms 337 μs | 74 ms 602 μs | 12,480 |
| 13 | 8,192 | 16,792 | 63.17 | 346 ms 878 μs | 75 ms 599 μs | 24,768 |
In the second set of tests, window bits were fixed at 7, and lookahead bits were varied from 3 to 7. Results are shown in Table 17.
- Best compression ratio (52.44%) was achieved with 4 lookahead bits with output size of 13,941 bytes.
- The fastest compression time (113 ms 335 μs) and decompression time (66 ms 521 μs) were achieved with 4 lookahead bits.
- Using lookahead bits larger than 4 generally worsens the compression ratio and increases compression/decompression time.
- Static RAM usage increases with lookahead bits approximately as 2lookahead bits − 1 due to static allocation of the lookahead buffer at initialization.
- Maximum stack usage during compression and decompression remained nearly constant (compression: 820 to 836 bytes; decompression: 396 to 404 bytes).
- Level 1 produced the best compression ratio (66.75%) with an output size of 17,745 bytes and the fastest compression (32 ms 067 μs) and decompression (5 ms 726 μs) times.
- Maximum stack usage remained constant (compression: 1024 bytes; decompression: 340 bytes).
Table 17. Heatshrink compression and decompression evaluation with window bits set to 7 on the bit-packed binary file.
| Lookahead bits | Maximum match length (bytes) | Compressed output size (bytes) | Compression ratio (%) | Compression time (ms:μs) | Decompression time (ms:μs) | Static RAM usage (bytes) |
|---|---|---|---|---|---|---|
| 3 | 8 | 14,338 | 53.94 | 115 ms 896 μs | 68 ms 794 μs | 552 |
| 4 | 16 | 13,941 | 52.44 | 113 ms 335 μs | 66 ms 521 μs | 560 |
| 5 | 32 | 14,378 | 54.09 | 117 ms 606 μs | 67 ms 578 μs | 576 |
| 6 | 64 | 14,815 | 55.73 | 130 ms 555 μs | 68 ms 634 μs | 608 |
| 7 | 128 | 15,251 | 57.37 | 1 s 149 ms 721 μs | 69 ms 688 μs | 672 |
4.7.3 LZ4
Compression was performed with LZ4_compress_fast(), varying the acceleration parameter from 1 to 16. Higher acceleration generally trades compression effectiveness for speed; under the ratio definition used here, this means that a faster setting can produce a larger compressed-to-input size ratio. Decompression used LZ4_decompress_safe(). Results of compression evaluation on the bit-packed binary file are shown in Table 18.
- Best compression ratio (68.57%) with output size of 18,228 bytes was observed with acceleration= 1.
- The fastest compression time (9 ms 437 μs) and decompression time (1 ms 379 μs) were observed with acceleration= 16.
- Static RAM usage remained constant at 57,472 bytes across all tested acceleration values.
- LZ4 showed substantially lower recorded compression and decompression times than Heatshrink, whereas Heatshrink achieved a smaller compressed-to-input size ratio. Raw static-RAM figures are not compared across implementations; normalized total application RAM is compared separately in Table 2.
- Maximum stack usage during compression and decompression remained nearly constant (compression: 1,024 bytes; decompression: 476–516 bytes).
Table 18. LZ4 compression and decompression evaluation on the bit-packed binary file.
| Acceleration | Compressed output size (bytes) | Compression ratio (%) | Compression time (ms:μs) | Decompression time (ms:μs) | Static RAM usage (bytes) |
|---|---|---|---|---|---|
| 1 | 18,228 | 68.57 | 42 ms 983 μs | 3 ms 958 μs | 57,472 |
| 2 | 18,632 | 70.09 | 35 ms 846 μs | 3 ms 431 μs | 57,472 |
| 3 | 19,106 | 71.87 | 31 ms 865 μs | 3 ms 148 μs | 57,472 |
| 4 | 19,588 | 73.69 | 29 ms 173 μs | 2 ms 871 μs | 57,472 |
| 5 | 20,202 | 76.00 | 26 ms 903 μs | 2 ms 864 μs | 57,472 |
| 6 | 20,680 | 77.79 | 25 ms 642 μs | 2 ms 693 μs | 57,472 |
| 7 | 22,280 | 83.81 | 21 ms 204 μs | 2 ms 439 μs | 57,472 |
| 8 | 22,800 | 85.77 | 19 ms 788 μs | 2 ms 400 μs | 57,472 |
| 9 | 24,033 | 90.41 | 15 ms 240 μs | 1 ms 708 μs | 57,472 |
| 10 | 23,836 | 89.67 | 15 ms 299 μs | 1 ms 862 μs | 57,472 |
| 11 | 23,557 | 88.62 | 15 ms 897 μs | 2 ms 023 μs | 57,472 |
| 12 | 23,882 | 89.84 | 14 ms 484 μs | 1 ms 746 μs | 57,472 |
| 13 | 24,657 | 92.76 | 13 ms 019 μs | 1 ms 720 μs | 57,472 |
| 14 | 25,182 | 94.73 | 10 ms 884 μs | 1 ms 524 μs | 57,472 |
| 15 | 25,072 | 94.32 | 10 ms 561 μs | 1 ms 446 μs | 57,472 |
| 16 | 25,692 | 96.65 | 9 ms 437 μs | 1 ms 379 μs | 57,472 |
4.7.4 FastLZ
FastLZ was evaluated at compression levels 1 and 2. The results of compression evaluation on a bit-packed binary file are shown in Table 19.
Table 19. FastLZ compression and decompression evaluation on the bit-packed binary file.
| Level | Compressed output size (bytes) | Compression ratio (%) | Compression time (ms:μs) | Decompression time (ms:μs) | Static RAM usage (bytes) |
|---|---|---|---|---|---|
| 1 | 17,745 | 66.75 | 32 ms 067 μs | 5 ms 726 μs | 58,793 |
| 2 | 17,749 | 66.77 | 33 ms 257 μs | 6 ms 328 μs | 58,793 |
4.7.5 Miniz
Miniz was evaluated at compression levels 1 to 9. The results of compression evaluation on a bit-packed binary file are shown in Table 20.
- All levels produced the same compression ratio (48.29%), output size (12,838 bytes), and static RAM usage (97,139 bytes). Increasing the Miniz level therefore had no effect on compressed size for this dataset.
- The fastest compression time (185 ms 94 μs) was observed at level 1. The fastest decompression time (11 ms 726 μs) was observed at levels 6, 7, and 8.
- Maximum stack usage remained constant (compression: 1024 bytes; decompression: 1,024 bytes).
- Miniz achieved the smallest compressed output among the evaluated algorithms, but the corresponding minimum-output configuration also had the largest normalized total application RAM and a relatively long compression time.
Table 20. Miniz compression and decompression evaluation on the bit-packed binary file.
| Level | Compressed output size (bytes) | Compression ratio (%) | Compression time (ms:μs) | Decompression time (ms:μs) | Static RAM usage (bytes) |
|---|---|---|---|---|---|
| 1 | 12,838 | 48.29 | 185 ms 094 μs | 11 ms 728 μs | 97,139 |
| 2 | 12,838 | 48.29 | 185 ms 213 μs | 11 ms 728 μs | 97,139 |
| 3 | 12,838 | 48.29 | 185 ms 217 μs | 11 ms 728 μs | 97,139 |
| 4 | 12,838 | 48.29 | 185 ms 219 μs | 11 ms 728 μs | 97,139 |
| 5 | 12,838 | 48.29 | 185 ms 217 μs | 11 ms 728 μs | 97,139 |
| 6 | 12,838 | 48.29 | 185 ms 220 μs | 11 ms 726 μs | 97,139 |
| 7 | 12,838 | 48.29 | 185 ms 220 μs | 11 ms 726 μs | 97,139 |
| 8 | 12,838 | 48.29 | 185 ms 217 μs | 11 ms 726 μs | 97,139 |
| 9 | 12,838 | 48.29 | 185 ms 218 μs | 11 ms 728 μs | 97,139 |
4.8 Evaluation of compression algorithms
Table 21 shows the smallest compressed output achieved by the different compression algorithms applied to the dataset stored in three different formats.
Table 21. Evaluation of compressed output in bytes.
| Compression algorithm | CSV file | Binary file | Bit-packed binary file |
|---|---|---|---|
| Initial size | 104,067 | 33,576 | 26,581 |
| LZW | 48,638 | 28,758 | 29,978 |
| LZW bit-packed | 33,848 | 16,177 | 16,863 |
| Heatshrink | 21,764 | 12,954 | 13,941 |
| LZ4 | 32,207 | 18,009 | 18,228 |
| FastLZ | 28,303 | 17,591 | 17,745 |
| Miniz | 16,029 | 11,352 | 12,838 |
Based on the performed tests, the smallest compressed file can be obtained using the Miniz compression algorithm on a binary file. When Miniz is used on the original CSV file, the compressed file size increases by only 4,677 bytes.
Additionally, the use of a bit-packed binary file can reduce the initial file size. However, after applying compression algorithms, the resulting compressed file is larger compared to using a binary file without bit-packing. Consequently, in our experiments, bit-packed binary format represents the best alternative only when no further compression is applied.
Table 22 shows the compression times of runs that achieved the smallest compressed output for the different algorithms and the dataset stored in three different formats.
Table 22. Evaluation of compression time for runs with the smallest compressed output.
| Compression algorithm | CSV file | Binary file | Bit-packed binary file |
|---|---|---|---|
| LZW | 163 ms 278 μs | 61 ms 926 μs | 54 ms 816 μs |
| LZW bit-packed | 168 ms 168 μs | 61 ms 926 μs | 54 ms 816 μs |
| Heatshrink | 812 ms 175 μs | 117 ms 291 μs | 113 ms 335 μs |
| LZ4 | 69 ms 619 μs | 42 ms 542 μs | 42 ms 983 μs |
| FastLZ | 61 ms 401 μs | 31 ms 653 μs | 32 ms 067 μs |
| Miniz | 761 ms 425 μs | 219 ms 512 μs | 185 ms 094 μs |
Across all minimum-output configurations, FastLZ on the binary representation had the shortest compression time (31 ms 653 μs); its output was 17,591 bytes and its total application RAM was 74,512 bytes. The absolute fastest configuration in the complete parameter sweep was LZ4 with acceleration = 16 on the bit-packed representation (9 ms 437 μs; 25,692-byte output). On that representation, LZ4's minimum output was 18,228 bytes at acceleration=1. The distinction prevents a size-optimized subset from being interpreted as a global speed ranking. Furthermore, in our experiments, the use of binary files both reduces compressed file size and decreases compression time.
Table 2 shows normalized total application RAM for the runs that achieved the smallest compressed output for each algorithm and representation. Each value includes both simultaneously allocated input/output buffers, algorithm static memory, and the larger measured stack maximum of compression or decompression. The normalization corrects the integration-dependent omission of common buffers from the raw LZW and Heatshrink linker figures.
Within the minimum-output subset, LZ4 had the lowest normalized total application RAM for all three representations: 226,761 bytes for CSV, 72,860 bytes for binary, and 58,496 bytes for bit-packed binary. These totals are close to the common buffer allocations, illustrating why algorithm-only working-memory figures cannot support an application-level RAM ranking.
5 Parametric transmission-time and energy model
Energy consumption was not measured in the experiments; therefore, this section provides a transparent parametric model rather than an experimental energy-efficiency result. It links compressed size to transmission time and transmission energy for a hypothetical communication interface. The model assumes constant effective payload throughput, supply voltage, and transmit-state current. Protocol headers, retransmissions, radio start-up, idle listening, voltage-converter losses, and the energy consumed by compression are not included unless explicitly added by the user.
Let N be the number of payload bytes, B the effective payload throughput in bytes per second, V the supply voltage, and Itx the current in the transmit state. Transmission time can be calculated using Equation 3 and energy can be calculated using Equation 4
ttx=NB(3)
and
Etx=VItxttx=VItxNB.(4)
For an uncompressed size Nu and compressed size Nc, the modeled transmission-time and transmission-energy reduction is identical under these assumptions in Equation 5:
Rtx=1-NcNu.(5)
For example, Miniz reduced the binary representation from 33,576 bytes to 11,352 bytes. The model therefore predicts a 66.19% reduction in payload transmission time and transmit-state energy relative to the uncompressed binary representation. Relative to transmitting the original 104,067-byte CSV representation, the reduction is 89.09%; this larger value includes both binary preprocessing and compression.
To illustrate the scale only, assume B = 9, 600 bytes/s, V = 3.3 V, and Itx = 50 mA. Transmitting the original CSV payload would take 10.840 s and require 1.789 J in the transmit state, whereas transmitting the 11,352-byte Miniz output would take 1.183 s and require 0.195 J. The modeled saving is 1.594 J per payload. These values are hypothetical and must not be interpreted as measurements for a particular transceiver.
Compression also consumes energy. A complete system comparison must therefore include Equation 6
Ecycle=Ecompression+Etx+Eother,(6)
where Ecompression is obtained from measured compression power and duration, and Eother contains sensing, storage, protocol, sleep, and conversion losses. Compression improves energy efficiency only when the transmit-energy saving exceeds the additional compression and memory-access energy. Because current consumption was not measured in this study, net energy savings and battery lifetime are outside the experimental claims; the equations above allow readers to insert parameters for their hardware and protocol.
6 Conclusion
Based on a series of compression tests and data preprocessing methods, the following statements can be made for the tested dataset:
- Miniz on the binary representation produced the smallest compressed output (11,352 bytes). Within the binary-representation minimum-output comparison, it also had the longest compression time (219 ms 512 μs) and the largest total application RAM requirement (113,216 bytes).
- Across all tested parameter settings, the shortest compression time was obtained by LZ4 with acceleration=16 on the bit-packed representation (9 ms 437 μs; 25,692-byte output). Across all minimum-output configurations, FastLZ on the binary representation had the shortest compression time (31 ms 653 μs); its output was 17,591 bytes and its total application RAM was 74,512 bytes.
- After common input/output buffers were included for every implementation, LZ4 on the bit-packed representation had the lowest total application RAM in the minimum-output subset (58,496 bytes). Heatshrink on that representation required 58,740 bytes, compressed in 113 ms 335 μs, and produced the second-smallest output (13,941 bytes).
- For this dataset, the bit-packed representation increased the compressed output relative to the ordinary binary representation because packing reduced byte alignment and recurring byte-level patterns used by the evaluated compressors.
No single compression configuration performs best in all three evaluated properties (compressed size, compression speed, and total application RAM); therefore, the algorithm and parameter setting must be chosen based on the property that is most important for the specific application.
Additionally, the results of the performed compression tests—and the choice of compression algorithm—are dataset-dependent. To determine the best compression algorithm and data preprocessing method for a specific application, all described tests should be performed on an application-specific dataset, and the results should be evaluated according to the application's requirements (compressed file size, compression time, and RAM memory consumption).
The performed experiments represent only a baseline comparison of different compression algorithms. No assumption is made that other numerical datasets will exhibit the same patterns; verification is required for each application-specific dataset.
In practical applications, the hardware limitations of the specific device also need to be taken into account. During experimental evaluation, we used the high-end and very capable STM32U575ZI microcontroller, which was able to run all evaluated compression algorithms. However, other microcontrollers may encounter hardware limitations, such as insufficient RAM or Flash memory, and a reduction in the size of the original dataset to be compressed may be required.
Based on the performed experiments and their analysis, the following two findings apply to the numerical time-series dataset evaluated in this study:
- The binary representation substantially reduced the input size relative to CSV before compression.
- Applying bit packing before compression reduced compression effectiveness and resulted in a larger compressed-to-input size ratio than the ordinary binary representation. This was associated with reduced byte alignment and the loss of recurring byte-level patterns used by the evaluated compressors.
The principal limitations of this study are the use of a single numerical time-series dataset, evaluation on one microcontroller platform, and the absence of retained repeated-run timing data.
Future work will focus on evaluating compression algorithms on additional datasets with different statistical properties, on different embedded platforms (microcontrollers), and on compression algorithms implemented in different programming languages. Repeated run-level timing data will also be retained so that the number of runs, mean, standard deviation, and range can be reported under fixed interrupt and warm-up conditions.
A complete benchmarking program is publicly available at https://github.com/tomasbaca438/embedded_systems_compression_algorithms_evaluation (Bača, 2026); using this program, compression algorithms can be evaluated directly on application-dependent datasets.
Generative AI statement
The author(s) declared that Generative AI was used in the creation of this manuscript. The author(s) used an AI-based language assistance tool solely for English language editing and grammar correction. All scientific content, analysis, interpretation, and final manuscript approval were performed by the author(s).
Any alternative text (alt text) provided alongside figures in this article has been generated by Frontiers with the support of artificial intelligence and reasonable efforts have been made to ensure accuracy, including review by the authors wherever possible. If you identify any issues, please contact us.
Publisher's note
All claims expressed in this article are solely those of the authors and do not necessarily represent those of their affiliated organizations, or those of the publisher, the editors and the reviewers. Any product that may be evaluated in this article, or claim that may be made by its manufacturer, is not guaranteed or endorsed by the publisher.
Footnotes
Edited by: Mohamed Wiem Mkaouer, University of Michigan-Flint, United States
Reviewed by: Safa S. S. Abdul-Jabbar, University of Baghdad, Iraq
Mahammad Masood Ahmad, Gandhi Institute of Technology and Management (GITAM), India
Statements
- Conflict of interest
The author(s) declared that this work was conducted in the absence of any commercial or financial relationships that could be construed as a potential conflict of interest.
- Funding
The author(s) declared that financial support was not received for this work and/or its publication.
- Data availability
The datasets presented in this study can be found in online repositories. The names of the repository/repositories and accession number(s) can be found below: https://github.com/tomasbaca438/embedded_systems_compression_algorithms_evaluation.
- Author contributions
TB: Formal analysis, Investigation, Software, Supervision, Validation, Writing – original draft. LF: Conceptualization, Data curation, Investigation, Methodology, Software, Writing – review & editing. PŠ: Data curation, Methodology, Resources, Visualization, Writing – review & editing. OK: Investigation, Software, Validation, Writing – review & editing.
References
- Ariya Hidayat (n.d.). FastLZ: Lightning-Fast Lossless Compression Library.
- Atomic Object (n.d.). Heatshrink: Data Compression Library for Embedded Systems.
- Auli-Llinas F. (2023). Fast and efficient entropy coding architectures for massive data compression. Technologies 11: 132. doi: doi:10.3390/technologies11050132
- Bača T. (2026). Embedded Systems Compression Algorithms Evaluation. University of Žilina. Source code and experimental dataset (Accessed May 25, 2026).
- David Bryant (n.d.). LZW-AB: LZW compression with adaptive bit lengths.
- Ehrlich P., Radke S. (2013). “Energy-aware software development for embedded systems in hw/sw co-design,” in Proceedings of the 2013 IEEE 16th international symposium on design and diagnostics of electronic circuits and systems (DDECS) (Karlovy Vary: IEEE), 232 – 235. doi: doi:10.1109/DDECS.2013.6549823
- Free Software Foundation and Jean-loup Gailly (2025). GNU Gzip: General file (De)compression.
- Guberović E., Krišto F., Krivić P., Čavrak I. (2019). “Assessing compression algorithms on iot sensor nodes,” in Proceedings of the 2019 42nd international convention on information and communication technology, electronics and microelectronics (MIPRO) (Opatija: IEEE), 913 – 918. doi: doi:10.23919/MIPRO.2019.8756995
- Hosseini M. (2025). A survey of data compression algorithms and their applications. CoRR abs/2506.10000. doi: doi:10.48550/arXiv.2506.10000
- Hubacz M., Trybus B. (2022). Data alignment on embedded cpus for programmable control devices. Electronics 11: 2174. doi: doi:10.3390/electronics11142174
- Hwang G., Cho K., Han C., Oh H., Yoon Y., Lee S. (2021). Lossless decompression accelerator for embedded processor with gui. Micromachines 12: 145. doi: doi:10.3390/mi12020145
- Jayasankar U., Thirumal V., Ponnurangam D. (2021). A survey on data compression techniques: from the perspective of data quality, coding schemes, data type and applications. J. King Saud Univ. Comput. Inf. Sci. 33, 119 – 140. doi: doi:10.1016/j.jksuci.2018.05.006
- Jiang H., Lin S.-J. (2020). A rolling hash algorithm and the implementation to lz4 data compression. IEEE Access 8: 1. doi: doi:10.1109/ACCESS.2020.2974489
- Kadhum Idrees S., Azar J., Couturier R., Kadhum Idrees A., Gechter F. (2025). Sz4iot: an adaptive lightweight lossy compression algorithm for diverse iot devices and data types. J. Supercomput. 81, 392 – 417. doi: doi:10.1007/s11227-024-06667-9
- Kamal R. (2008). Embedded Systems: Architecture, Programming, and Design, 1st Edn. Boston, MA: McGraw-Hill Higher Education.
- Keskin S., Sevli O., Okatan E. (2023). Single and binary performance comparison of data compression algorithms for text files. Bitlis Eren. Üniv. Fen Bilim. Derg. 12, 783 – 796. doi: doi:10.17798/bitlisfen.1301546
- Ko Y., Chadwick A., Bates D., Mullins R. (2021). Lane compression: a lightweight lossless compression method for machine learning on embedded systems. ACM Trans. Embed. Comput. Syst. 20, 1 – 26. doi: doi:10.1145/3431815
- Kulkarni M., Jagdale D., Joshi R., Joshi A., Kadam S. (2025). “Text compression techniques: a study of LZW, RLE, huffman, and extended huffman coding,” in Congress on Smart Computing Technologies, eds. M. Saraswat, A. Rajan, and A. Chakravorty (Singapore: Springer Nature Singapore), 747 – 761. doi: doi:10.1007/978-981-96-6254-8_54
- Li C.-H., Nowick S. M. (2005). “An architecture-oriented approach to code compression for embedded processors,” in Proceedings of the IEEE workshop on application-specific processors (WASP-05) (Jersey, NJ: Department of Computer Science). Presentation; full-length paper included in unpublished workshop proceedings; workshop affiliated with CODES-05.
- Lin C. H., Wang W.-J., Chen J.-C., Lin C.-W. (2020). “Code compression for embedded systems”. in Embedded, Cyber-Physical, and IoT Systems: Essays Dedicated to Marilyn Wolf on the Occasion of Her 60th Birthday, eds. S. S. Bhattacharyya, M. Potkonjak, and S. Velipasalar (Cham: Springer International Publishing), 115 – 147. doi: doi:10.1007/978-3-030-16949-7_6
- Liu Z., Song S. (2026). Improving lz4 for effective compression and efficient query. Proc. ACM Manag. Data 4, 1 – 26. doi: doi:10.1145/3786660
- Lu T., Xia W., Zou X., Xia Q. (2020). “Adaptively compressing iot data on the resource-constrained edge” in Proceedings of the 3rd USENIX workshop on hot topics in edge computing (Hotedge 20) (Boston, MA: USENIX Association).
- LZ4 Project (n.d.). LZ4 - Extremely Fast Compression.
- LZ4 Project Developers (n.d.). LZ4: Extremely Fast Compression Algorithm.
- Mark N. (1989). LZW data compression. Dr. Dobb's J.
- Nikam V., Dhande S. (2023). A historical perspective on approaches to data compression. Math. Comput. Sci. 8, 68 – 72. doi: doi:10.11648/j.mcs.20230803.11
- Ozturk O., Saputra H., Kandemir M., Kolcu I. (2005). “Access pattern-based code compression for memory-constrained embedded systems,” in Proceedings of the design, automation and test in Europe, Vol. 2, (Munich: IEEE), 882 – 887. doi: doi:10.1109/DATE.2005.46
- Piatkowski D., Puslecki T., Walkowiak K. (2024). Study of the impact of data compression on the energy consumption required for data transmission in a microcontroller-based system. Sensors 24: 224. doi: doi:10.3390/s24010224
- Rich Geldreich (n.d.). Miniz: Single-File Zlib-Replacement Compression Library.
- Rodrigues C., Jishnu E. M., Nair C. R., Krishnan M. S. (2022). “A study on data compression algorithms for its efficiency analysis,” in Ubiquitous Intelligent Systems, eds. P. Karuppusamy, I. Perikos, and F. P. García Márquez (Singapore: Springer Singapore), 475 – 488. doi: doi:10.1007/978-981-16-3675-2_36
- Sahu M., Panda J. (2023). “A time efficient approach to data compression for lzw algorithm,” in Proceedings of the 2023 annual international conference on emerging research areas: international conference on intelligent systems (AICERA/ICIS) (Kanjirapally: IEEE), 1 – 3. doi: doi:10.1109/AICERA/ICIS59538.2023.10420326
- Sharma G. (2020). Analysis of huffman coding and lempel-ziv-welch (lzw) coding as data compression techniques. Int. J. Sci. Res. Comput. Sci. Eng. 8, 37 – 44.
- Sharma M. K., Alapatt B. P., Sharma V., Shanbhog M. (2025). “A comparative review of lossless text compression algorithms: from classic techniques to hybrid models,” in Proceedings of the 2025 2nd international conference on advanced computing and emerging technologies (ACET) (Ghaziabad: IEEE), 1 – 5. doi: doi:10.1109/ACET67282.2025.11430241
- The Wuffs Authors (n.d.). LZW (Lempel Ziv Welch) Compression.
- Tu K., Puchala D. (2022). Variable-to-variable huffman coding: optimal and greedy approaches. Entropy 24: 1447. doi: doi:10.3390/e24101447
- Wiseman Y. (2007). The relative efficiency of data compression by lzw and lzss. Data Sci. J. 6, 1 – 6. doi: doi:10.2481/dsj.6.1
- Xie Y. (2003). “Analysis of two code compression algorithms for embedded systems,” in Proceedings of the 2003 5th International Conference on ASIC Vol. 2 (Beijing: IEEE), 773 – 776. doi: doi:10.1109/ICASIC.2003.1277325
- Yang L., Dick R. P., Lekatsas H., Chakradhar S. (2010). Online memory compression for embedded systems. ACM Trans. Embed. Comput. Syst. 9, 1 – 24. doi: doi:10.1145/1698772.1698785
- Yoon S., Jun S., Cho Y., Lee K., Jang H., Han T. H. (2020). Optimized lossless embedded compression for mobile multimedia applications. Electronics 9: 868. doi: doi:10.3390/electronics9050868
- Zurawski R. (2018). Embedded Systems Handbook:Embedded Systems Design and Verification. Boca Raton, FL:CRC Press. doi: doi:10.1201/9781315218281
Citation
Bača, T., et al. (2026). Experimental evaluation of compression algorithms for memory-constrained embedded systems. Frontiers in Computer Science, Volume 8. https://doi.org/
- Received
- Accepted
- Published
- Volume
- 8 - 2026
Copyright
Copyright © 2026 Bača, Formanek, Ševčík and Karpiš.
License: https://creativecommons.org/licenses/by/4.0/
*Correspondence: Tomáš Bača
Article metrics
- Views
- 0
- Downloads
- 0
- Citations
- 0
- Shares
- 0
