Documentation

Hello Epochly

Your first steps with Epochly - a beginner-friendly tutorial to get started.

Before You Start

Installation

Install Epochly using pip:

pip install epochly

Verify Installation

Check that Epochly is properly installed:

epochly doctor

Expected output:

✓ Epochly is installed correctly
✓ Python version: 3.11.5
✓ NumPy available
✓ JIT compiler: Numba 0.58.0
✓ System: 8 CPU cores detected

Example 1: Basic Decorator

The simplest way to use Epochly is with the @epochly.optimize() decorator:

import epochly
@epochly.optimize()
def calculate_sum(n):
"""Calculate sum of squares"""
total = 0
for i in range(n):
total += i ** 2
return total
# Use the optimized function
result = calculate_sum(10_000_000)
print(f"Result: {result}")

Expected output:

Result: 333333283333335000000

What happened? Epochly automatically analyzed your function and applied the optimal optimization level. The loop was JIT-compiled for faster execution.

Example 2: With Performance Monitoring

Track performance metrics with the @epochly.performance_monitor decorator:

import epochly
@epochly.performance_monitor
@epochly.optimize()
def calculate_sum(n):
"""Calculate sum of squares with monitoring"""
total = 0
for i in range(n):
total += i ** 2
return total
# Run the function
result = calculate_sum(10_000_000)
# Check the status
status = epochly.get_status()
print(f"Status: {status}")

Expected output:

Result: 333333283333335000000
Status: {
'initialized': True,
'enhancement_level': 2,
'total_calls': 1,
'total_time': 0.125,
'optimizations_active': True
}

What's new? The performance_monitor decorator tracks execution time and call counts. Use get_status() to retrieve metrics.

Example 3: Specifying Enhancement Level

Control the optimization level explicitly using the EnhancementLevel enum:

import epochly
from epochly import EnhancementLevel
@epochly.optimize(level=EnhancementLevel.LEVEL_2_JIT)
def calculate_sum(n):
"""Calculate with JIT compilation"""
total = 0
for i in range(n):
total += i ** 2
return total
# First call: JIT compilation happens
result1 = calculate_sum(10_000_000)
print(f"First call result: {result1}")
# Second call: Uses compiled code (much faster!)
result2 = calculate_sum(10_000_000)
print(f"Second call result: {result2}")

Expected output:

First call result: 333333283333335000000
Second call result: 333333283333335000000

Note: The first call is slower due to compilation. Subsequent calls are 10-50x faster!

Available levels:

  • EnhancementLevel.LEVEL_0_BASELINE - No optimization (monitoring only)
  • EnhancementLevel.LEVEL_1_THREADING - Threading for I/O-bound tasks
  • EnhancementLevel.LEVEL_2_JIT - JIT compilation for CPU-bound code
  • EnhancementLevel.LEVEL_3_MULTICORE - Multi-core parallelism
  • EnhancementLevel.LEVEL_4_GPU - GPU acceleration (requires GPU)

Example 4: Running via CLI

Run Python scripts through Epochly's CLI for automatic optimization:

Basic CLI Usage

epochly script.py

Save this as script.py:

# script.py
def calculate_sum(n):
total = 0
for i in range(n):
total += i ** 2
return total
if __name__ == "__main__":
result = calculate_sum(10_000_000)
print(f"Result: {result}")

Run it:

epochly script.py

Expected output:

[Epochly] Initializing with level 2...
Result: 333333283333335000000
[Epochly] Execution time: 0.125s

Verbose Mode

Get detailed information with the -v flag:

epochly -v script.py

Expected output:

[Epochly] Initializing with level 2...
[Epochly] JIT compiler: Numba 0.58.0
[Epochly] CPU cores: 8
[Epochly] Optimizing hot paths...
Result: 333333283333335000000
[Epochly] Functions optimized: 1
[Epochly] Execution time: 0.125s
[Epochly] Speedup: 15.2x

Example 5: Context Manager

Use optimize_context() to optimize specific code blocks:

import epochly
# Code outside context runs normally
data = list(range(1_000_000))
print("Data prepared")
# Optimize only this block
with epochly.optimize_context(level=1):
# This code benefits from threading optimization
import requests
urls = [
"https://api.example.com/data1",
"https://api.example.com/data2",
"https://api.example.com/data3",
]
results = []
for url in urls:
response = requests.get(url)
results.append(response.json())
print(f"Fetched {len(results)} responses")
# Code after context runs normally
print("Processing complete")

Expected output:

Data prepared
Fetched 3 responses
Processing complete

Use case: The context manager is perfect when you only want to optimize specific sections of your code, like I/O operations or computationally intensive blocks.

Multiple Contexts

You can nest or chain contexts with different levels:

import epochly
# I/O operations with threading
with epochly.optimize_context(level=1):
files = ["data1.txt", "data2.txt", "data3.txt"]
data = [open(f).read() for f in files]
print(f"Loaded {len(data)} files")
# CPU-intensive work with JIT
with epochly.optimize_context(level=2):
total = sum(int(x) ** 2 for x in range(1_000_000))
print(f"Computed: {total}")

Checking Status

Using the API

Check Epochly's status programmatically:

import epochly
# Get current status
status = epochly.get_status()
print(f"Initialized: {status['initialized']}")
print(f"Enhancement Level: {status['enhancement_level']}")
print(f"Mode: {status['mode']}")
print(f"Total Calls: {status.get('total_calls', 0)}")
print(f"Total Time: {status.get('total_time', 0):.3f}s")

Expected output:

Initialized: True
Enhancement Level: 2
Mode: balanced
Total Calls: 5
Total Time: 0.542s

Using the CLI

Check status from the command line:

epochly status

Expected output:

Epochly Status:
Version: 1.0.0
Initialized: Yes
Default Level: 2 (JIT)
JIT Available: Yes (Numba)
CPU Cores: 8
GPU Available: No

Detailed Status

Get more detailed information:

epochly status --detailed

Expected output:

Epochly Detailed Status:
Version: 1.0.0
Python: 3.11.5
Platform: Linux-5.15.0-x86_64
Configuration:
Enhancement Level: 2
Mode: balanced
Max Workers: 8
JIT Backend: numba
Performance:
Total Calls: 15
Total Time: 1.234s
Average Time: 0.082s
Cache Hits: 10
System:
CPU Cores: 8
Available Memory: 16.0 GB
GPU: Not available

Quick Reference

Here's a summary of what you've learned:

import epochly
from epochly import EnhancementLevel
# 1. Basic decorator (auto-select level)
@epochly.optimize()
def my_function():
pass
# 2. With performance monitoring
@epochly.performance_monitor
@epochly.optimize()
def monitored_function():
pass
# 3. Specify level with enum
@epochly.optimize(level=EnhancementLevel.LEVEL_2_JIT)
def jit_function():
pass
# 4. Context manager
with epochly.optimize_context(level=1):
# Optimized code here
pass
# 5. Check status
status = epochly.get_status()

CLI commands:

# Install and verify
pip install epochly
epochly doctor
# Run scripts
epochly script.py
epochly -v script.py
# Check status
epochly status
epochly status --detailed

Next Steps

Now that you understand the basics, explore these topics:

Common Beginner Questions

Q: Do I need to change my code?

A: No! Just add the @epochly.optimize() decorator or use the CLI.

Q: Will it work with existing libraries?

A: Yes! Epochly works with NumPy, pandas, scikit-learn, and more.

Q: What if I don't specify a level?

A: Epochly automatically selects the best level for your workload.

Q: How do I know if it's working?

A: Use @epochly.performance_monitor or epochly status to see metrics.

Q: Is there any overhead?

A: Minimal. The decorator adds microseconds of overhead while providing 2-50x speedups.