Introduction

In recent times, Rust has gained popularity as a systems programming language, often compared to C due to its performance and safety features.

This page delves into analysis using Rust to interact with the RDK-B data model, focusing on key aspects like memory consumption, performance, and integration challenges.

Memory Consumption

Memory efficiency is an important factor for embedded systems.

Let's look at the memory footprint of our applications written in C and Rust.

root@RaspberryPi-Gateway:~# ls -la
-rwxr-x--- 1 root root  13472 Jul 11 08:39 ccsponc
-rwxr-x--- 1 root root 292520 Jul 11 08:39 ccsponrust

The C application (ccsponc) has a significantly smaller footprint (13,472 bytes) compared to the Rust application (ccsponrust) at 292,520 bytes. 

Furthermore, Rust applications should be stripped and optimized to reduce their size. Stripping removes debug information and other non-essential data, making the final executable smaller and more efficient. 293KB is stripped and optimized for the size of the application.

The detailed breakdown of the Rust application's memory usage is as follows:

Rust Application Memory Breakdown

Component

.text

Size

Crate

std

14.1%

236.9 KiB

97.0%

ccsponrust

0.3%

4.7 KiB

1.9%

Unknown

0.1%

2.4 KiB

1.0%

Total

14.5%

244.4 KiB

100.0%

It is obvious the main contributor to the larger size of the Rust application is the std (standard) library, which is statically linked in our PoC.

To mitigate this, the Rust community suggests to dynamically link the standard library, potentially reducing the executable size to approximately 20 KB. This will make the size difference between Rust and C applications negligible.

Performance Comparison

Performance tests were conducted using rbus libraries to communicate with the RDKB data model. The tests involved making 100 sequential requests to retrieve a Wi-Fi SSID value.

For ccsponrust: 

./ccsponrust --command get --component gl_component --name Device.WiFi.SSID.1.SSID

For ccsponc: 

./ccsponc --command get --component gl_component --name Device.WiFi.SSID.1.SSID

C Application Performance

root@RaspberryPi-Gateway:~# time ./test_c.sh  
real    0m2.169s
user    0m0.656s
sys     0m1.385s

Rust Application Performance

root@RaspberryPi-Gateway:~# time ./test_rust.sh  
real    0m2.298s
user    0m0.710s
sys     0m1.481s

The performance difference between the C and Rust applications is minimal.

The C application completes the test in 2.169 seconds, while the Rust application takes 2.298 seconds.

This slight delay in Rust can be attributed to the overhead of its safety checks and runtime features.

Integration Challenges

One of the main challenges when using Rust is integrating existing C libraries. Unlike C, where headers are included directly, Rust requires creating wrappers to interface with C libraries. This process involves:

  • Recreating C structures and enums in Rust.
  • Ensuring proper memory management across the FFI (Foreign Function Interface) boundary.
  • Writing Rust wrappers for C functions.

The complexity of this task depends on the number and intricacy of the functions and structures from the C libraries that need to be used.

Conclusion

Rust presents a viable option for developing middle-ware applications for routers to interact with different data models, including RDKB. Its advantages in memory safety and concurrency make it an attractive alternative to C, despite the larger binary size due to the standard library and the additional effort required for integrating C libraries. With dynamic linking and optimized FFI bindings, Rust could potentially match C in both footprint and performance.

  • No labels