Python Examples¶
Basic Energy Measurement¶
# hello_energy.py
def greet(name):
message = f"Hello, {name}!"
return message
def calculate_sum(n):
total = sum(range(n))
return total
def main():
result = greet("CodeGreen")
print(result)
total = calculate_sum(1000000)
print(f"Sum: {total}")
if __name__ == "__main__":
main()
Measure:
# Coarse mode: total program energy
codegreen measure python hello_energy.py
# Fine mode: per-function breakdown
codegreen measure python hello_energy.py -g fine
# With visualization
codegreen measure python hello_energy.py -g fine --export-plot energy.html
Algorithm Comparison¶
Compare energy consumption of different sorting implementations:
# sorting_comparison.py
import random
def generate_data(size):
random.seed(42)
return [random.randint(1, 10000) for _ in range(size)]
def bubble_sort(arr):
n = len(arr)
arr = arr.copy()
for i in range(n):
for j in range(n - i - 1):
if arr[j] > arr[j + 1]:
arr[j], arr[j + 1] = arr[j + 1], arr[j]
return arr
def quick_sort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quick_sort(left) + middle + quick_sort(right)
def main():
data = generate_data(5000)
bubble_result = bubble_sort(data)
print(f"Bubble sort first: {bubble_result[0]}")
quick_result = quick_sort(data)
print(f"Quick sort first: {quick_result[0]}")
if __name__ == "__main__":
main()
Measure with per-function breakdown:
The energy timeline will show bubble_sort consuming significantly more energy than quick_sort due to O(n^2) vs O(n log n) complexity.
Optimization Before/After¶
Before (inefficient):
# string_concat_slow.py
def concatenate_slow(n):
result = ""
for i in range(n):
result += f"item{i},"
return result
def main():
result = concatenate_slow(50000)
print(f"Length: {len(result)}")
if __name__ == "__main__":
main()
After (optimized):
# string_concat_fast.py
def concatenate_fast(n):
parts = []
for i in range(n):
parts.append(f"item{i},")
return "".join(parts)
def main():
result = concatenate_fast(50000)
print(f"Length: {len(result)}")
if __name__ == "__main__":
main()
Compare:
codegreen measure python string_concat_slow.py -o slow.json
codegreen measure python string_concat_fast.py -o fast.json
The join-based version typically uses 70-85% less energy.
Matrix Operations¶
CPU-intensive computation:
# matrix_multiply.py
def create_matrix(rows, cols, value):
return [[value] * cols for _ in range(rows)]
def matrix_multiply(a, b):
rows_a, cols_a = len(a), len(a[0])
cols_b = len(b[0])
result = [[0] * cols_b for _ in range(rows_a)]
for i in range(rows_a):
for j in range(cols_b):
for k in range(cols_a):
result[i][j] += a[i][k] * b[k][j]
return result
def main():
size = 200
a = create_matrix(size, size, 1.5)
b = create_matrix(size, size, 2.0)
result = matrix_multiply(a, b)
print(f"Result[0][0]: {result[0][0]}")
if __name__ == "__main__":
main()
Recursive vs Iterative¶
# fibonacci.py
def fibonacci_recursive(n):
if n <= 1:
return n
return fibonacci_recursive(n - 1) + fibonacci_recursive(n - 2)
def fibonacci_iterative(n):
if n <= 1:
return n
a, b = 0, 1
for _ in range(2, n + 1):
a, b = b, a + b
return b
def main():
n = 30
print(f"Recursive: {fibonacci_recursive(n)}")
print(f"Iterative: {fibonacci_iterative(n)}")
if __name__ == "__main__":
main()
The recursive version consumes orders of magnitude more energy due to exponential function calls.
Common CLI Patterns¶
# Quick energy measurement of any command (no instrumentation)
codegreen run python script.py --repeat 10
# Energy budget enforcement (exits non-zero if exceeded)
codegreen run --budget 5.0 python script.py
# Basic measurement (coarse, 2 checkpoints)
codegreen measure python script.py
# Fine granularity (all functions)
codegreen measure python script.py -g fine
# JSON output to stdout
codegreen measure python script.py --json
# Save results to file
codegreen measure python script.py -o results.json
# Interactive HTML plot
codegreen measure python script.py -g fine --export-plot energy.html
# Static PNG plot (requires matplotlib)
codegreen measure python script.py -g fine --export-plot energy.png
# Keep instrumented code for inspection
codegreen measure python script.py --no-cleanup
# Pass arguments to the script
codegreen measure python script.py -- arg1 arg2
# Analyze without running (static analysis only)
codegreen analyze python script.py --verbose
Best Practices¶
- Use fine mode for profiling:
-g fineshows per-function energy breakdown - Use coarse mode for totals: Default mode gives total energy with minimal overhead
- Consistent data: Use same seeds for random data when comparing
- Multiple runs: Average 3-5 runs for stable results
- Avoid I/O during profiling: File I/O adds measurement noise
- Return results: Use function return values to prevent dead code elimination