TL;DR for operators

A development team wants to identify energy-expensive Java methods early, without repeatedly profiling every code change on controlled hardware. Source-level features such as complexity, calls, loops, and control flow appear to offer a cheap signal because they can be extracted before the software runs.

In this study, those features were almost useless without runtime evidence. When the researchers reran the same Random Forest prediction setup after removing execution time, predictive $R^2$ fell from 0.454 to 0.005. Code features that look operationally meaningful therefore provided almost no useful prediction until a timing signal was added.

The practical choice is not between static analysis and full energy profiling for every change. Teams can combine static features with lightweight timing in CI to rank methods for deeper investigation, while reserving direct energy measurement for selected methods and decisions that require defensible estimates. The resulting model is a triage tool, not a production-grade energy meter.

Static code features fail the first operational test

The premise is familiar. Energy measurement is expensive to repeat during development: programs must run under controlled conditions, profilers must observe them, and total energy must somehow be assigned to individual methods. A static model promises to move part of that work earlier. It could inspect the source and flag methods whose structure suggests higher energy consumption.

Muhammad Imran, Vincenzo Stoico, and Ivano Malavolta test that proposition directly in Static Metrics Are Insufficient: Predicting Java Method Energy Usage with Execution Time.1 Their result is not that source structure has no relationship with energy. It is that the evaluated structural indicators cannot support reliable prediction without evidence about what happens when the code runs.

The sharpest result comes from rerunning the same Random Forest prediction setup after removing execution time. With static features plus timing, the model reached $R^2 = 0.454$. With static features alone, it fell to 0.005. Its mean absolute percentage error also worsened from 1.75 to 2.27.

An $R^2$ of 0.005 means the model explained almost none of the variation in the measured, log-transformed energy values. Complexity counts and call structure may describe what a method could do, but they do not reveal how often it executes, which paths are taken, how much work its inputs trigger, or how the JVM and hardware handle that work.

That distinction changes the investment decision. A static-only energy score may look suitable for dashboards, code review gates, or automated refactoring recommendations. Under this study’s conditions, such a score would have almost no demonstrated predictive foundation.

The dataset joins source structure with sampled runtime behavior

The researchers collected Java implementations from Rosetta Code and the Computer Language Benchmarks Game. They extracted 33 method-level source features using srcML, covering method size and scope, control-flow constructs, cyclomatic complexity, variables, method calls, and selected Java API usage. Encoding method scope expanded the complete modeled input set to 35 features.

The dynamic side required two profilers. Async-profiler supplied method execution times, while JoularJX estimated how program-level CPU and DRAM energy should be attributed to individual methods. That attribution is not a direct electricity reading for each method. It is derived from sampled runtime observations, so short-lived or infrequently observed calls may receive missing or zero estimates.

Programs were warmed up and executed 20 times with fixed inputs. Runs used a one-millisecond sampling interval and a 30-second cool-down, on a controlled testbed with fixed CPU frequency, disabled hyper-threading, minimal background activity, and single-threaded subjects.

The filtering pipeline is consequential. Static features were extracted for 2,786 methods. Complete static and dynamic information was available for 902, but zero-energy observations were removed, leaving 265 methods for model training. Energy and execution time were log-transformed because both were strongly long-tailed.

The authors then compared 11 regression algorithms under five-fold cross-validation. Seven feature settings across those models produced 77 untuned configurations. This breadth helps test whether algorithm choice, feature selection, or parameter tuning can compensate for limited inputs. It does not compensate for the small final sample.

The paper also reports inconsistent corpus totals across sections: 853 files and 812 tasks in one account, compared with 768 files and 815 tasks elsewhere. This discrepancy does not negate the reported model comparisons, but it weakens confidence in the dataset accounting.

Execution time carries most of the predictive signal

The execution-time removal experiment is the paper’s main diagnostic evidence. It isolates the contribution of runtime duration while preserving the wider prediction setup. The collapse from $R^2 = 0.454$ to 0.005 shows that model performance is not primarily generated by the static feature set.

Execution time captures several factors that the source representation omits. A method with modest structural complexity may execute millions of times. A complex method may run once. Fixed source counts do not record input-dependent loop iterations, invocation frequency, JIT compilation effects, allocation behavior, cache interactions, or which control-flow branches are exercised.

After establishing this dependence on timing, the researchers compared how strongly individual inputs contributed to the model’s predictions. Their SHAP analysis ranked execution time first. Internal method calls and other structural features supplied secondary signal, while cyclomatic complexity appeared repeatedly across feature-selection procedures.

This is a more precise conclusion than “static metrics do not matter.” Internal calls and complexity may help distinguish methods with similar runtimes or identify code worth inspecting. They cannot replace runtime context in the tested full-program setting.

The mechanism also helps explain why static-only results from isolated snippets may not transfer cleanly. A method embedded in a running application inherits behavior from its callers, inputs, invocation count, JVM state, and surrounding workload. Its energy attribution is therefore partly a property of execution context, not solely of its source text.

Better feature selection does not repair weak inputs

The leading untuned result used Random Forest with variance-threshold feature selection. It retained 24 features and achieved:

Configuration Features MSE MAE MAPE $R^2$
Random Forest, variance threshold 24 7.038 2.008 1.693 0.463
Random Forest, all features 35 7.152 2.024 1.745 0.454
AdaBoost, variance threshold 24 7.218 2.162 2.152 0.453

The improvement from feature selection was 0.009 in $R^2$. That may make the model smaller and its inputs easier to inspect, but it does not change the model’s practical reliability. Random Forest occupied four of the five leading untuned configurations, suggesting reasonable consistency among the tested algorithms. The Decision Tree baseline was much weaker, with $R^2$ near 0.05.

Hyperparameter tuning added even less. Tuned Random Forest configurations converged around $R^2 = 0.462$, effectively matching the untuned results. Tuned AdaBoost declined from 0.453 to 0.436.

These tests serve a different purpose from the timing removal experiment. Feature selection evaluates whether redundant or noisy inputs are suppressing performance. Tuning tests whether default model settings are leaving substantial accuracy unused. Neither provides evidence of a second predictive breakthrough. Together, they show that algorithm refinement cannot recover information absent from the input representation.

For teams building internal energy-analysis pipelines, this changes the order of work. Representative execution data, profiler coverage, and workload design deserve attention before broad model searches or elaborate tuning campaigns.

An $R^2$ near 0.46 supports triage, not energy accounting

The strongest model explains less than half of the variance in the log-transformed target. Its cross-validation $R^2$ ranged from 0.224 to 0.567 across folds. Predictions tended to follow the center of the energy distribution and deviated more at its tails.

That behavior matters operationally. Energy optimization often focuses on high-consumption outliers, precisely where a regression model pulled toward the center may be less dependable. A moderate average score can coexist with poor estimates for the methods a team most needs to identify correctly.

The target transformation also affects interpretation. Performance metrics were calculated on logarithmic energy values rather than raw joules. A tolerable error in log space can correspond to a substantial multiplicative error in the original measurement scale. MAPE values around 1.7 therefore should not be read as evidence of precise physical accounting.

A defensible product claim would be that the model may help prioritize methods for investigation under conditions similar to the training environment. It would not be defensible to present its output as a portable estimate of how many joules a production method will consume.

Developer tooling should separate ranking from validation

The paper directly shows: adding measured execution time transforms the prediction problem, while static metrics alone provide near-zero predictive value in this benchmark. Model selection, feature selection, and tuning have much smaller effects than the timing input.

Cognaptus inference: an energy-aware development workflow can use static metrics and lightweight timing as a screening layer. A CI job could run representative tests, collect method timing, combine it with structural features, and rank candidates for deeper analysis. Internal call counts and complexity can also help explain why a method entered the review queue.

The ranking should determine where measurement effort goes, not settle the optimization decision. Before changing an algorithm, replacing a library, or accepting a regression, teams should validate the affected methods with direct energy profiling under workloads that reflect production behavior.

This suggests a three-stage operating model:

  1. Extract static features continuously because they are cheap and interpretable.
  2. Add timing from representative executions to produce a provisional ranking.
  3. Measure energy directly for high-ranked methods and material engineering decisions.

The released dataset, subject code, static-analysis implementation, machine-learning pipeline, feature-selection outputs, tuning results, and SHAP analyses make the paper a useful starting point for internal experiments. The replication package supports reuse of the modeling phase, although its README states that the dynamic measurement phase itself is not included.

The deployment boundary is defined by runtime and measurement context

The study uses self-contained, algorithmic, single-threaded programs with fixed inputs. That is a controlled environment for comparison, but it excludes much of production Java: framework lifecycles, asynchronous services, database access, network I/O, background workers, event-driven execution, and multithreaded contention.

The energy labels are also tied to JoularJX, RAPL-supported CPU and DRAM domains, the tested JVM, sampling configuration, and hardware. Peripheral consumption is omitted. Short method executions may be missed at one-millisecond sampling, and code coverage was not measured, so source features may describe paths that the fixed inputs never exercised.

These are deployment conditions, not footnote-sized qualifications. A model trained in one JVM and hardware environment may learn a relationship that changes when the runtime, processor architecture, workload mix, profiler, or application style changes.

Production adoption therefore requires a new validation exercise, not merely installation of the published model. The unresolved issue is whether richer runtime signals, broader workloads, and larger real-world datasets can raise accuracy without making the measurement process nearly as expensive as direct profiling.

The operational lesson is about evidence collection

The paper’s strongest result is a failed shortcut. Static complexity, calls, and control flow do not provide an adequate proxy for method-level Java energy use under the tested full-program conditions.

Execution time supplies enough runtime context to produce a moderate ranking signal. Feature selection makes only a small difference, and parameter tuning does not materially improve the leading models. The bottleneck lies in what the system observes, not in how aggressively the regressor is optimized.

For engineering teams, the appropriate response is not to abandon source analysis. It is to give each signal a narrower job. Static features can explain and organize code. Timing can improve prioritization. Direct energy measurement remains necessary when the decision depends on actual consumption.

Cognaptus: Automate the Present, Incubate the Future.


  1. Muhammad Imran and Vincenzo Stoico and Ivano Malavolta (2026). Static Metrics Are Insufficient: Predicting Java Method Energy Usage with Execution Time. arXiv:2607.06124. https://arxiv.org/abs/2607.06124 ↩︎