Fruit C++ Dependency Injection Framework

repository·master·Indexed 23 days ago

https://github.com/google/fruit

A C++ dependency injection framework inspired by Java's Guice that uses metaprogramming and C++11 features to provide compile-time error detection. It allows developers to organize code into modular components assembled into an injector to manage object lifecycles and dependencies.

Tokens
1.4K
Snippets
3
Records
6
Agent score
34%

What's inside Fruit

  1. Overview of Fruit dependency injection

    master

    Fruit is a C++ dependency injection framework inspired by Java's Guice. It leverages C++ metaprogramming and C++11 features to detect many injection errors at compile-time.

    Key concepts:

    • Components (Modules): Units of implementation code that can be assembled into larger components.
    • Injector: An object created from a component that has no requirements, which provides instances of the interfaces exposed by that component.
  2. Format benchmark results with format_bench_results.py

    master

    After running benchmarks, use format_bench_results.py to convert raw results into human-readable tables. You can use a table definition (from the tables folder) to specify the layout. You can also provide a --baseline-benchmark-results file to compare current results against a previous run (e.g., before and after a commit).

    # Format a single result file
    $ ~/projects/fruit/extras/benchmark/format_bench_results.py \
        --benchmark-results ~/fruit_bench_results.txt \
        --benchmark-tables-definition ~/projects/fruit/extras/benchmark/tables/fruit_wiki.yml
    
    # Compare current results against a baseline
    $ ~/projects/fruit/extras/benchmark/format_bench_results.py \
        --benchmark-results ~/fruit_bench_results_after.txt \
        --benchmark-tables-definition ~/projects/fruit/extras/benchmark/tables/fruit_wiki.yml \
        --baseline-benchmark-results ~/fruit_bench_results_before.txt
  3. Run manual benchmarks and profiling

    master

    To run benchmarks manually (e.g., for profiling with callgrind), follow these steps:

    1. Build the main Fruit project with RelWithDebInfo.
    2. Use generate_benchmark.py to create a specific benchmark project.
    3. Build the generated benchmark project.
    4. Run the resulting executable through a profiler like valgrind.
    $ cd ~/projects/fruit
    $ mkdir build
    $ cd build
    $ CXX=g++-6 cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo
    $ make -j 10
    $ cd ..
    $ mkdir generated-benchs
    $ extras/benchmark/generate_benchmark.py \
        --compiler g++-6 \
        --fruit-sources-dir ~/projects/fruit \
        --fruit-build-dir ~/projects/fruit/build \
        --num-components-with-no-deps 10 \
        --num-components-with-deps 90 \
        --num-deps 10 \
        --output-dir generated-benchs \
        --generate-debuginfo=true
    $ cd generated-benchs
    $ make -j 10
    $ valgrind \
        --tool=callgrind \
        --simulate-cache=yes \
        --dump-instr=yes \
        ./main 10000
  4. Run Fruit benchmark suites with run_benchmarks.py

    master

    Use run_benchmarks.py to execute automated benchmark suites that measure metrics such as performance, compile time, and executable size. You must provide paths to the benchmark definition, the output file, and the source directories for Fruit and any related libraries (like Boost.DI).

    $ ~/projects/fruit/extras/benchmark/run_benchmarks.py \
        --continue-benchmark=true \
        --benchmark-definition ~/projects/fruit/extras/benchmark/suites/fruit_full.yml \
        --output-file ~/fruit_bench_results.txt \
        --fruit-sources-dir ~/projects/fruit \
        --fruit-benchmark-sources-dir ~/projects/fruit \
        --boost-di-sources-dir ~/projects/boost-di
  5. Available benchmark table definitions

    master

    Table definitions in the tables folder determine how results are displayed:

    • fruit_wiki.yml: The main definition containing tables used in Fruit's wiki.
    • fruit_internal.yml: A detailed version of fruit_wiki.yml that includes developer-centric metrics, such as splitting setup time into component creation time and normalization time.
  6. Available Fruit benchmark suites

    master

    The following benchmark suites are available in the suites folder:

    • fruit_full.yml: Full set of Fruit benchmarks using the Fruit 3.x API.
    • fruit_mostly_full.yml: A subset of fruit_full.yml.
    • fruit_quick.yml: A small subset designed for quick evaluation (approx. 10-15 min). The number of runs is capped at 10, resulting in wider confidence intervals.
    • fruit_single.yml: Runs Fruit runtime benchmarks under a single compiler and one combination of flags. Capped at 8 runs; useful for performance optimization development.
    • fruit_debug.yml: A very quick suite used to verify that benchmarking code still works after changes. Results are not meaningful for performance analysis.
    • boost_di: Exercises the Boost.DI library instead of Fruit.