C++ 3 Min. Lesezeit

C++-Performance mit Folly steigern

Diesen Artikel teilen
Boosting C++ Performance with Folly

Die Folly von Facebook entwickelte Bibliothek Folly ist eine Sammlung wiederverwendbarer C++-Bibliothekskomponenten, die die C++-Standardbibliothek ergänzen und die Leistung von C++-Anwendungen steigern sollen. Folly legt den Schwerpunkt auf Effizienz und bietet hochoptimierte Komponenten, die besonders für leistungskritische Anwendungen geeignet sind. Zu den wichtigsten performanceorientierten Funktionen der Bibliothek gehören:

1. Effiziente Datenstrukturen

Folly stellt mehrere auf hohe Leistung optimierte Datenstrukturen bereit:

  • folly::small_vector: Ein optimierter, vektorähnlicher Container mit einem kleinen Puffer für Inline-Speicherung. Dadurch werden bei kleinen Größen weniger Heap-Allokationen benötigt, was Cache-Lokalität und Performance verbessert.
  #include <folly/small_vector.h>

  void example() {
      folly::small_vector<int, 5> vec;
      for (int i = 0; i < 10; ++i) {
          vec.push_back(i);
      }
  }
  • folly::F14 Hash-Tabellen: Hocheffiziente Implementierungen von Hash-Tabellen (F14ValueMap, F14NodeMap, F14VectorMap, sowie die entsprechenden Set-Varianten). Diese Hash-Tabellen bieten gegenüber herkömmlichen Hash-Tabellen eine bessere Einfüge- und Suchleistung sowie eine effizientere Speichernutzung.
  #include <folly/container/F14Map.h>

  void example() {
      folly::F14FastMap<int, std::string> map;
      map[1] = "one";
      map[2] = "two";
  }
  • folly::AtomicHashMap: Eine hochgradig nebenläufige Hash-Map für Szenarien, die schnelle, lockfreie Operationen erfordern.
  #include <folly/AtomicHashMap.h>

  void example() {
      folly::AtomicHashMap<int, std::string> map(100);
      map.insert(1, "one");
      map.insert(2, "two");
  }

2. Nebenläufigkeit und Parallelität

Folly bietet fortgeschrittene Nebenläufigkeitsprimitive und Hilfsfunktionen, die die Leistung in Multithreading-Umgebungen verbessern:

  • folly::Future und folly::Promise: Sie ermöglichen eine komfortable Verarbeitung asynchroner Berechnungen und Callbacks und unterstützen damit eine effiziente und skalierbare Nebenläufigkeit.
  #include <folly/futures/Future.h>
  #include <iostream>

  void example() {
      folly::Promise<int> promise;
      auto future = promise.getFuture();

      future.thenValue([](int value) {
          std::cout << "Received: " << value << std::endl;
      });

      promise.setValue(42);
  }
  • folly::CPUThreadPoolExecutor: Eine für CPU-intensive Aufgaben optimierte Thread-Pool-Implementierung mit konfigurierbarem Parallelitätsgrad und effizienter Aufgabenplanung.
  #include <folly/executors/CPUThreadPoolExecutor.h>
  #include <folly/futures/Future.h>
  #include <iostream>

  void example() {
      folly::CPUThreadPoolExecutor executor(4); // 4 threads
      auto future = folly::makeFuture()
                      .via(&executor)
                      .thenValue([](auto) {
                          std::cout << "Task executed in thread pool." << std::endl;
                          return 42;
                      });
      future.wait();
  }

3. Speicherverwaltung

Folly enthält Hilfsfunktionen und Allokatoren, die die Speicherverwaltung optimieren, Fragmentierung reduzieren und die Leistung bei Allokation und Freigabe verbessern:

  • folly::Arena: Ein effizienter Speicherallokator für Szenarien mit vielen kleinen Allokationen und Freigaben. Er minimiert den Overhead und verbessert die Cache-Lokalität.
  #include <folly/memory/Arena.h>

  void example() {
      folly::SysArena arena;
      int* p = static_cast<int*>(arena.allocate(sizeof(int)));
      *p = 42;
  }

4. String-Verarbeitung

Folly bietet mehrere optimierte String-Hilfsfunktionen, die ihre Pendants aus der Standardbibliothek in der Performance übertreffen sollen:

  • folly::fbstring: Eine hochoptimierte String-Implementierung, die std::string in vielen Szenarien übertreffen soll, insbesondere bei der Small String Optimization und einem geringeren Speicher-Overhead.
  #include <folly/FBString.h>

  void example() {
      folly::fbstring str = "Hello, Folly!";
      std::cout << str << std::endl;
  }

5. Serialisierung und Deserialisierung

Folly stellt effiziente Hilfsfunktionen für Serialisierung und Deserialisierung bereit:

  • folly::io::Cursor und folly::io::QueueAppender: Diese Klassen bieten effiziente Mechanismen zum Lesen aus und Schreiben in Byte-Streams, was für leistungsstarke Netzwerkanwendungen entscheidend ist.
  #include <folly/io/IOBuf.h>
  #include <folly/io/Cursor.h>

  void example() {
      auto buf = folly::IOBuf::create(100);
      folly::io::QueueAppender appender(buf.get(), 0);
      appender.writeBE<uint32_t>(42);

      folly::io::Cursor cursor(buf.get());
      uint32_t value = cursor.readBE<uint32_t>();
      std::cout << value << std::endl;
  }

6. Benchmarking und Tests

Folly enthält Benchmarking- und Testwerkzeuge, mit denen Entwickler die Performance effektiv messen und optimieren können:

  • folly::Benchmark: Ein schlankes Benchmarking-Framework zur Messung der Performance von Codeabschnitten.
  #include <folly/Benchmark.h>

  void example() {
      folly::runBenchmarks();
  }

Durch den Einsatz dieser Komponenten und Hilfsfunktionen aus der Folly-Bibliothek können C++-Entwickler leistungsstarke, skalierbare und wartbare Anwendungen erstellen. Die Kombination aus optimierten Datenstrukturen, effizienter Speicherverwaltung, fortgeschrittenen Nebenläufigkeitsprimitiven und leistungsfähigen Werkzeugen zur String-Verarbeitung macht Folly zu einem äußerst wertvollen Baustein für die Entwicklung performancekritischer Software.

Diesen Artikel teilen