Rust Bibliothek und Binary: Performance-Paket erstellen

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Ein Paket, zwei Entitäten: Mythos oder Realität?

\n\n

Stellen Sie sich vor: Sie haben eine fantastische Bibliothek in Rust für die Arbeit mit großen Datenmengen geschrieben. Sie ist blitzschnell, sicher und elegant. Aber Sie brauchen nicht nur eine API für andere Entwickler, sondern auch ein fertiges CLI-Tool, um die Bibliothek zu testen oder in Pipelines zu verwenden. Da taucht die klassische Frage auf, die tausende Aufrufe auf Stack Overflow gesammelt hat: „Package with both a library and a binary?“ (Ein Paket, das sowohl eine Bibliothek als auch eine ausführbare Datei enthält).

\n\n

Für Rust-Neulinge klingt das nach einem Rätsel. Für erfahrene Entwickler ist es eine Aufgabe zur Optimierung der Projektstruktur und Leistung. In diesem Artikel beantworten wir diese Frage nicht nur, sondern tun dies mit Fokus auf Optimierung und Performance – zwei Dinge, die Rust am meisten geliebt machen.

\n\n

Wir zeigen Ihnen, wie Sie ein solches Paket richtig organisieren, Code-Duplizierung vermeiden, die Kompilierung beschleunigen und Ihr Binary wirklich schnell machen. Los geht's!

\n\n

Paketstruktur: Cargo.toml regelt alles

\n\n

In Rust kann ein einzelnes Cargo-Paket sowohl eine Bibliothek (lib) als auch mehrere Binaries (bin) enthalten. Das ist keine Magie, sondern eine einfache Ordnerstruktur-Konvention. Sehen wir uns ein minimales Beispiel an.

\n\n

Erstellen wir ein Projekt:

\n\n
cargo new my_tool --lib
\n\n

Jetzt ändern wir die Datei Cargo.toml, um explizit anzugeben, dass wir sowohl eine Bibliothek als auch ein Binary haben:

\n\n
[package]\nname = "my_tool"\nversion = "0.1.0"\nedition = "2021"\n\n[lib]\nname = "my_tool_lib"\npath = "src/lib.rs"\n\n[[bin]]\nname = "my_tool"\npath = "src/main.rs"\n\n[dependencies]\n
\n\n

Die Ordnerstruktur sieht dann so aus:

\n\n
my_tool/\n├── Cargo.toml\n├── src/\n│   ├── lib.rs      // Bibliothek\n│   └── main.rs     // Binary\n
\n\n

Ganz einfach, oder? Aber der Teufel steckt im Detail. Wenn Sie einfach den Code aus der Bibliothek in die main.rs kopieren, erhalten Sie Duplizierung und Performance-Probleme. Sie müssen klüger vorgehen.

\n\n

Der richtige Ansatz: Binary nutzt die Bibliothek

\n\n

Das Binary sollte die Bibliothek wie eine externe Crate importieren. Auch wenn sie sich im selben Paket befinden. Das reduziert nicht nur die Duplizierung, sondern ermöglicht dem Rust-Compiler auch eine bessere Optimierung durch Cross-Crate-Optimierung (LTO).

\n\n

Beispiel src/lib.rs:

\n\n
pub fn calculate(data: &[u64]) -> u64 {\n    data.iter().sum()\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    #[test]\n    fn test_calculate() {\n        assert_eq!(calculate(&[1, 2, 3]), 6);\n    }\n}\n
\n\n

Beispiel src/main.rs:

\n\n
use my_tool_lib::calculate;\n\nfn main() {\n    let numbers = vec![10, 20, 30];\n    println!("Summe: {}", calculate(&numbers));\n}\n
\n\n

Beachten Sie: Wir verwenden my_tool_lib – den Namen, den wir der Bibliothek in Cargo.toml gegeben haben. Der Compiler verknüpft sie automatisch zu einem Binary, bewahrt aber die Modularität.

\n\n

Performance-Optimierung: LTO, Inline und Benchmarks

\n\n

Nachdem die Struktur steht, sprechen wir über das Wesentliche – wie Sie das Maximum aus Ihrem Paket herausholen. Denn wenn Sie ein Tool zur Datenverarbeitung erstellen, zählt jede Mikrosekunde.

\n\n

1. Link-Time Optimization (LTO) aktivieren

\n\n

LTO ermöglicht es dem Compiler, Code über Crate-Grenzen hinweg zu optimieren. Ohne LTO werden Funktionen aus Bibliothek und Binary getrennt optimiert. Mit LTO – wie eine Einheit.

\n\n

Fügen Sie in Cargo.toml hinzu:

\n\n
[profile.release]\nlto = true\ncodegen-units = 1\n
\n\n

Das verlängert die Kompilierzeit, macht das Binary aber deutlich schneller. Für die Bildungsseite pythonlib.ru ist es wichtig zu betonen: LTO ist der Standard für Production-Builds in Rust.

\n\n

2. Inline-Hinweise nutzen

\n\n

Wenn Ihre Bibliothek kritische Funktionen enthält,

Blogs

Buchempfehlungen