Polyglot Energy Analysis

Joule can measure and optimize the energy consumption of code written in other languages. The --lift-run flag lifts foreign code into Joule's intermediate representation, applies energy analysis, and executes it with full energy tracking.

Quick Start

# Measure energy in a Python script
joulec --lift-run python script.py

# Measure energy in a JavaScript file
joulec --lift-run js app.js

# Measure energy in C code
joulec --lift-run c program.c

# Apply energy optimization before running
joulec --energy-optimize --lift-run python script.py

# Generate JSON energy report
joulec --lift python script.py --energy-report report.json

# Set energy budget (exit code 1 if exceeded)
joulec --lift python script.py --energy-budget 100nJ

How It Works

The polyglot pipeline has four stages:

  1. Parse: The source file is parsed by a language-specific parser (Python, JavaScript, or C) into Joule's LiftedModule representation.

  2. Lower: The lifted AST is lowered to MIR (Mid-level IR), the same representation used for native Joule code. Variables, functions, classes, and control flow are all mapped to MIR constructs.

  3. Optimize (optional): When --energy-optimize is passed, four energy optimization passes are applied to the MIR before execution.

  4. Execute: The MIR is JIT-compiled via the Cranelift backend and executed in-memory. Energy consumption is tracked throughout execution and reported at the end.

Supported Languages

Python

Comprehensive support for Python syntax and semantics:

FeatureStatus
Functions, closures, lambdasSupported
Classes (single and multiple inheritance)Supported
List/dict/set comprehensionsSupported
f-stringsSupported
Ternary expressionsSupported
enumerate/zipSupported
match/case (Python 3.10+)Supported
Walrus operator (:=)Supported
try/except/finallySupported (guard patterns)
Slicing with stepSupported
Default argumentsSupported
*args, **kwargsSupported
Generator expressionsSupported
String methods (30+)Supported
List methods (20+)Supported
Dict methods (15+)Supported
Math moduleSupported
Print with end=Supported
True divisionSupported
BigInt overflow handlingSupported

JavaScript

Comprehensive support for JavaScript syntax and semantics:

FeatureStatus
Functions, arrow functionsSupported
Classes (single inheritance)Supported
Template literalsSupported
DestructuringSupported
Spread operatorSupported
switch/caseSupported
for-in/for-ofSupported
do-whileSupported
Bitwise operatorsSupported
typeofSupported
Nullish coalescing (??)Supported
Optional chaining (?.)Supported
Array methods (20+)Supported
String methods (15+)Supported
Object methodsSupported
Math objectSupported
console.logSupported
this keywordSupported

C

Basic support for C code:

FeatureStatus
FunctionsSupported
Basic types (int, float, double, char)Supported
ArraysSupported
PointersSupported
Control flow (if, while, for)Supported
stdio (printf, scanf)Supported
math.h functionsSupported

TypeScript

TypeScript types are erased before analysis — the energy profile is identical to JavaScript. See the TypeScript Guide for details.

FeatureStatus
Everything in JavaScriptSupported
Type annotationsStripped
Interfaces, type aliases, genericsStripped
Access modifiers (public/private)Stripped
Enums (simple)Converted to constants

Go

FeatureStatus
Functions, closures, variadicSupported
for, for range, if/else, switchSupported
Slices, maps, structs, methodsSupported
Goroutines (go)Supported (sequential analysis)
Channels (chan, <-)Supported
deferSupported
Multiple return valuesSupported
fmt, math, strings, strconvSupported

Rust

FeatureStatus
Functions, closures, impl blocksSupported
for/while/loop, if/else, matchSupported
let/let mut, ownership annotationsSupported
Structs, enums, Option, ResultSupported
Vec, HashMap, String, BoxSupported
Iterator chains (.map/.filter/.fold)Supported
println!, format!, vec!Supported
Traits (signatures only)Supported

Energy Recommendations

When analyzing code, Joule detects common energy anti-patterns and suggests fixes. Categories include:

  • ALGORITHM -- Nested loops where a hash set would be O(1)
  • ALLOCATION -- Heap allocation inside hot loops
  • REDUNDANCY -- Recomputed values that could be hoisted
  • DATA STRUCTURE -- Linear search where a set/map is more efficient
  • LOOP -- Missing early exits, unbounded iteration
  • STRING -- String concatenation in loops (O(n^2))
  • MEMORY -- Cache-unfriendly access patterns
  • PRECISION -- Float arithmetic where integer suffices

See the per-language guides for language-specific examples of each pattern.

Runtime System

The lift-run runtime provides 100+ shim functions that bridge language-specific operations to native code:

String Operations

str_new, str_concat, str_len, str_print, str_from_int, str_from_float, str_eq, str_index, str_slice, str_contains, str_mul, str_cmp, str_upper, str_lower, str_trim, str_split, str_replace, str_starts_with, str_ends_with, str_index_of, and more.

List Operations

list_new, list_push, list_get, list_set, list_len, list_pop, list_sort, list_reverse, list_copy, list_append, list_index_of, list_contains, list_slice, list_map, list_filter, and more.

Dict Operations

dict_new, dict_set, dict_get, dict_len, dict_get_default, dict_pop, dict_update, dict_setdefault, dict_keys, dict_values, dict_items, dict_contains, and more.

Class Desugaring

Classes from Python and JavaScript are desugared to dictionary-backed standalone functions:

# Python source
class Counter:
    def __init__(self, start):
        self.count = start

    def increment(self):
        self.count += 1
        return self.count

This is lowered to:

  • Counter____init__(self, start) -- constructor function
  • Counter__increment(self) -- method function
  • self is a dictionary with fields as key-value pairs

Multiple inheritance is supported using BFS method resolution order (MRO).

Energy Optimization Passes

When --energy-optimize is used, four passes optimize the lifted code:

  1. Constant Propagation -- Propagate known values, fold constant expressions
  2. Dead Code Elimination -- Remove unreachable and unused code
  3. Loop Optimization -- Reduce redundant computation in loops
  4. Strength Reduction -- Replace expensive operations with cheaper equivalents

Test Coverage

The polyglot pipeline is validated by 1,220 tests across 8 test suites:

SuiteCountDescription
Tiered validation90Core feature coverage
Edge cases80Corner cases and error handling
Domain10050 Python + 50 JS across 5 domains
Stdlib10050 Python + 50 JS: string/list methods, default args
Classes50Inheritance, MRO, properties, static methods
Advanced50Closures, generators, decorators, metaclasses
Syntax50Language-specific syntax features
Coverage700Division, print, comprehensions, string ops

Total: 1,220/1,220 (100% pass rate)

Examples

Python Energy Analysis

# fibonacci.py
def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n - 1) + fibonacci(n - 2)

result = fibonacci(30)
print(f"Result: {result}")
$ joulec --lift-run python fibonacci.py
Result: 832040
Energy consumed: 0.00234 J

JavaScript Energy Analysis

// sort.js
function quickSort(arr) {
    if (arr.length <= 1) return arr;
    const pivot = arr[0];
    const left = arr.filter(x => x < pivot);
    const right = arr.filter(x => x > pivot);
    return [...quickSort(left), pivot, ...quickSort(right)];
}

const data = Array.from({length: 1000}, () => Math.floor(Math.random() * 10000));
const sorted = quickSort(data);
console.log(`Sorted ${sorted.length} elements`);
$ joulec --lift-run js sort.js
Sorted 1000 elements
Energy consumed: 0.00891 J

Energy-Optimized Execution

$ joulec --energy-optimize --lift-run python fibonacci.py
Result: 832040
Energy consumed: 0.00198 J (15.4% reduction)

Static Analysis Mode

For energy analysis without execution, use --lift instead of --lift-run:

# Analyze without running
joulec --lift python script.py

# Output includes per-function energy estimates

This performs the parsing and lowering steps but stops before JIT compilation, producing a static energy report for each function.

Per-Language Guides

For detailed anti-patterns, optimization tips, and worked examples specific to each language:

  • Python Guide -- 100+ runtime shims, classes, comprehensions, f-strings
  • JavaScript Guide -- Arrow functions, template literals, array methods
  • TypeScript Guide -- Type erasure, identical energy to JavaScript
  • C Guide -- Memory allocation patterns, cache analysis
  • Go Guide -- Goroutines, channels, slice operations
  • Rust Guide -- Iterator chains, zero-cost abstractions

Further Reading