Skip to content

Performance

Performance is a critical design consideration for Astrea, as aerospace applications often require real-time computation or processing of large datasets. This document outlines Astrea's performance architecture, optimization strategies, and benchmarking methodologies.

Performance Goals

Target Performance Characteristics

Metric Target Measurement
Computational Overhead ≤ 5% vs. hand-optimized C Micro-benchmarks
Memory Overhead Zero for abstractions Static analysis
Compile-time Performance < 10s for full rebuild CI measurements
Cache Efficiency > 95% L1 cache hit rate Performance profiling
Vector Utilization SIMD usage where applicable Compiler analysis

Performance Principles

  1. Zero-Cost Abstractions: High-level features compile to optimal machine code
  2. Compile-Time Computation: Move calculations from runtime to compile-time
  3. Cache-Friendly Design: Data structures optimized for memory access patterns
  4. SIMD Optimization: Leverage vector instructions for bulk operations
  5. Minimal Allocations: Prefer stack allocation and avoid unnecessary heap usage

Optimization Strategies

Compile-Time Optimization

Template Metaprogramming

// Coordinate transformation matrices computed at compile-time
template<typename FromFrame, typename ToFrame>
consteval auto transformation_matrix() {
    if constexpr (std::is_same_v<FromFrame, ToFrame>) {
        return math::Matrix3::identity();
    } else if constexpr (is_constant_rotation_v<FromFrame, ToFrame>) {
        return precomputed_rotation<FromFrame, ToFrame>();
    } else {
        // Runtime computation required
        return std::nullopt;
    }
}

// Usage - matrix computed at compile-time when possible
auto transform_position(const Position<ICRF>& pos) {
    constexpr auto matrix = transformation_matrix<ICRF, J2000>();
    if constexpr (matrix.has_value()) {
        return matrix.value() * pos.vector();  // Compile-time matrix
    } else {
        return compute_runtime_transform<ICRF, J2000>(pos);
    }
}

Constant Expression Evaluation

// Physical constants computed at compile-time
namespace constants {
    constexpr auto earth_mu = 398600.4418 * units::km3_per_s2;
    constexpr auto earth_radius = 6378.137 * units::km;
    constexpr auto earth_j2 = 1.08262668e-3;

    // Derived constants computed at compile-time
    constexpr auto earth_angular_velocity = [] {
        constexpr auto sidereal_day = 86164.0905 * units::second;
        return 2.0 * std::numbers::pi * units::radian / sidereal_day;
    }();
}

Memory Layout Optimization

Structure of Arrays (SoA) Pattern

// Optimized for bulk operations and SIMD
template<std::size_t N>
class StateVector {
    // Separate arrays for each component (SoA)
    std::array<double, N> x_, y_, z_;           // Positions
    std::array<double, N> vx_, vy_, vz_;        // Velocities
    std::array<double, N> epochs_;              // Time stamps

public:
    // SIMD-friendly bulk propagation
    void propagate_kepler(double dt) {
        // Vectorized operations on entire arrays
        #pragma omp simd
        for (std::size_t i = 0; i < N; ++i) {
            // Kepler propagation for all states simultaneously
            auto [new_x, new_y, new_z, new_vx, new_vy, new_vz] = 
                kepler_step(x_[i], y_[i], z_[i], vx_[i], vy_[i], vz_[i], dt);

            x_[i] = new_x; y_[i] = new_y; z_[i] = new_z;
            vx_[i] = new_vx; vy_[i] = new_vy; vz_[i] = new_vz;
            epochs_[i] += dt;
        }
    }
};

Benchmarking and Profiling

Micro-Benchmarks

// Google Benchmark integration for performance testing
#include <benchmark/benchmark.h>

// Benchmark coordinate transformation performance
static void BenchmarkFrameTransform(benchmark::State& state) {
    auto position = Position<ICRF>{Vector3{1000.0, 2000.0, 3000.0} * units::km};
    auto epoch = EpochTT{1000.0 * units::julian_day};

    for (auto _ : state) {
        auto transformed = transform_position<ICRF, ITRF>(position, epoch);
        benchmark::DoNotOptimize(transformed);
    }
}
REGISTER_BENCHMARK(BenchmarkFrameTransform);

// Benchmark propagation performance
static void BenchmarkKeplerPropagation(benchmark::State& state) {
    auto initial_state = KeplerianState{/* ... */};
    auto dt = 60.0 * units::second;

    for (auto _ : state) {
        auto final_state = propagate_kepler(initial_state, dt);
        benchmark::DoNotOptimize(final_state);
    }
}
REGISTER_BENCHMARK(BenchmarkKeplerPropagation);

Astrea's performance architecture demonstrates that safety and performance are not mutually exclusive - through careful design and modern C++ techniques, we achieve both compile-time safety guarantees and runtime performance matching hand-optimized implementations.