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 = 0for i in range(n):total += i ** 2return total# Use the optimized functionresult = 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 = 0for i in range(n):total += i ** 2return total# Run the functionresult = calculate_sum(10_000_000)# Check the statusstatus = epochly.get_status()print(f"Status: {status}")
Expected output:
Result: 333333283333335000000Status: {'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 epochlyfrom epochly import EnhancementLevel@epochly.optimize(level=EnhancementLevel.LEVEL_2_JIT)def calculate_sum(n):"""Calculate with JIT compilation"""total = 0for i in range(n):total += i ** 2return total# First call: JIT compilation happensresult1 = 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: 333333283333335000000Second 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 tasksEnhancementLevel.LEVEL_2_JIT- JIT compilation for CPU-bound codeEnhancementLevel.LEVEL_3_MULTICORE- Multi-core parallelismEnhancementLevel.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.pydef calculate_sum(n):total = 0for i in range(n):total += i ** 2return totalif __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 normallydata = list(range(1_000_000))print("Data prepared")# Optimize only this blockwith epochly.optimize_context(level=1):# This code benefits from threading optimizationimport requestsurls = ["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 normallyprint("Processing complete")
Expected output:
Data preparedFetched 3 responsesProcessing 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 threadingwith 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 JITwith 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 statusstatus = 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: TrueEnhancement Level: 2Mode: balancedTotal Calls: 5Total Time: 0.542s
Using the CLI
Check status from the command line:
epochly status
Expected output:
Epochly Status:Version: 1.0.0Initialized: YesDefault Level: 2 (JIT)JIT Available: Yes (Numba)CPU Cores: 8GPU Available: No
Detailed Status
Get more detailed information:
epochly status --detailed
Expected output:
Epochly Detailed Status:Version: 1.0.0Python: 3.11.5Platform: Linux-5.15.0-x86_64Configuration:Enhancement Level: 2Mode: balancedMax Workers: 8JIT Backend: numbaPerformance:Total Calls: 15Total Time: 1.234sAverage Time: 0.082sCache Hits: 10System:CPU Cores: 8Available Memory: 16.0 GBGPU: Not available
Quick Reference
Here's a summary of what you've learned:
import epochlyfrom 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 managerwith epochly.optimize_context(level=1):# Optimized code herepass# 5. Check statusstatus = epochly.get_status()
CLI commands:
# Install and verifypip install epochlyepochly doctor# Run scriptsepochly script.pyepochly -v script.py# Check statusepochly statusepochly status --detailed
Next Steps
Now that you understand the basics, explore these topics:
- Decorator Patterns - Advanced decorator usage
- Context Manager Patterns - Scoped optimization techniques
- Configuration Examples - Fine-tune Epochly settings
- Enhancement Levels - Deep dive into optimization levels
- Best Practices - Optimization strategies
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.