Raxol.Core.Performance.Optimizer (Raxol v2.0.1)

View Source

Refactored Performance optimization strategies with GenServer-based memoization.

This module provides the same optimization techniques as the original but uses supervised state management instead of Process dictionary for memoization.

Migration Notes

The memoize macro now uses Raxol.Core.Performance.Memoization.Server instead of Process dictionary, providing better fault tolerance and monitoring.

Summary

Functions

Profiles and suggests algorithm improvements.

Optimizes GenServer calls by batching.

Batches operations to reduce overhead.

Implements caching for expensive operations.

Optimizes concurrent operations using Task.async_stream.

Optimizes ETS table operations.

Initializes a connection pool with the given configuration.

Implements lazy loading for large datasets.

Memoizes function results to avoid recomputation.

Optimizes list operations using appropriate data structures.

Optimizes database queries to prevent N+1 problems.

Implements read-through cache pattern.

Reduces memory usage by implementing streaming where possible.

Optimizes string concatenation for better performance.

Optimizes recursive operations using tail recursion.

Implements circuit breaker pattern for external calls.

Implements connection pooling for external resources.

Functions

analyze_algorithm(name, implementations)

Profiles and suggests algorithm improvements.

batch_genserver_calls(server, messages, opts \\ [])

Optimizes GenServer calls by batching.

Examples

batch_genserver_calls(MyServer, messages, batch_size: 50)

batch_process(enumerable, opts, fun)

Batches operations to reduce overhead.

Examples

batch_process records, batch_size: 100 do |batch|
  Repo.insert_all(Record, batch)
end

cached(operation, opts, list)

(macro)

Implements caching for expensive operations.

Options

  • :ttl - Time to live in milliseconds (default: 60_000)
  • :key - Cache key (required)
  • :refresh - Whether to refresh cache on hit (default: false)

Examples

cached :expensive_calculation, key: "calc_123", ttl: 300_000 do
  perform_expensive_calculation(123)
end

concurrent_map(enumerable, fun, opts \\ [])

Optimizes concurrent operations using Task.async_stream.

Options

  • :max_concurrency - Maximum concurrent tasks (default: System.schedulers_online())
  • :timeout - Task timeout in milliseconds (default: 5000)
  • :ordered - Maintain order of results (default: true)

Examples

concurrent_map users, &send_email/1, max_concurrency: 10

ets_batch_insert(table, records, opts \\ [])

Optimizes ETS table operations.

Examples

ets_batch_insert(:my_table, records, batch_size: 1000)

execute_with_cache(operation, opts, fun)

init_connection_pool(pool_name, opts \\ [])

Initializes a connection pool with the given configuration.

Options

  • :size - Pool size (default: 5)
  • :max_overflow - Maximum overflow connections (default: 10)
  • :worker - Worker module for connections
  • :worker_args - Arguments for worker initialization

Examples

init_connection_pool(:database, 
  size: 5, 
  max_overflow: 10,
  worker: MyConnectionWorker,
  worker_args: [host: "localhost", port: 5432]
)

lazy_stream(operation, list)

(macro)

Implements lazy loading for large datasets.

Examples

lazy_stream :large_file_reader do
  File.stream!("large_file.txt")
  |> Stream.map(&process_line/1)
end

memoize(call, list)

(macro)

Memoizes function results to avoid recomputation.

Now uses GenServer-based caching instead of Process dictionary.

Examples

defmodule Calculator do
  use Raxol.Core.Performance.Optimizer

alias Raxol.Core.Runtime.Log

  memoize expensive_calculation(n) do
    # Complex calculation
    factorial(n) * fibonacci(n)
  end
end

optimize_list_ops(operation_type, data, transformer)

Optimizes list operations using appropriate data structures.

Examples

# For frequent prepends, use lists
optimize_list_ops :prepend, initial_list do |list|
  [new_item | list]
end

# For frequent lookups, convert to map
optimize_list_ops :lookup, list do |list|
  Map.new(list, & {&1.id, &1})
end

optimize_query(list)

(macro)

Optimizes database queries to prevent N+1 problems.

Examples

# Before optimization
users = Repo.all(User)
users_with_posts = Enum.map(users, fn user ->
  %{user | posts: Repo.all(assoc(user, :posts))}
end)

# After optimization
users_with_posts = optimize_query do
  User |> preload(:posts) |> Repo.all()
end

read_through_cache(key, loader, opts \\ [])

Implements read-through cache pattern.

stream_process(file_path, processor)

Reduces memory usage by implementing streaming where possible.

Examples

stream_process "large_file.csv" do |line|
  parse_csv_line(line)
  |> process_record()
end

string_builder(parts)

Optimizes string concatenation for better performance.

Examples

# Instead of multiple concatenations
result = str1 <> str2 <> str3 <> str4

# Use
result = string_builder([str1, str2, str3, str4])

tail_recursive_sum(list)

Optimizes recursive operations using tail recursion.

Examples

# Convert recursive function to tail-recursive
def sum([]), do: 0
def sum([h | t]), do: h + sum(t)

# Becomes
tail_recursive_sum(list)

with_circuit_breaker(name, fun, opts \\ [])

Implements circuit breaker pattern for external calls.

with_pooled_connection(pool_name, fun)

Implements connection pooling for external resources.

Uses poolboy if available, otherwise creates a simple connection pool using Registry.

Examples

with_pooled_connection(:database, fn conn ->
  MyRepo.query(conn, "SELECT * FROM users")
end)