ConceptioArchivearXiv CS
arXiv CSopen access

Static Metrics Are Insufficient: Predicting Java Method Energy Usage with Execution Time

Unknown · 2026 · arxiv_cs
arXiv CS · Papers · License: Open Access · 2026
Open Source ↗Direct PDF ↓
machine learning, deep learning, neural networks

Static Metrics Are Insufficient: Predicting Java Method Energy Usage with Execution Time Muhammad Imran1 , Vincenzo Stoico2 , and Ivano Malavolta2 University of L’Aquila, L’Aquila, Italy [email protected] 2 Vrije Universiteit Amsterdam, Amsterdam, The Netherlands [email protected], [email protected]

arXiv:2607.06124v1 [cs.SE] 7 Jul 2026

1

Abstract. The increasing energy demand of software systems is raising concerns about their environmental impact and associated costs. Reasoning on energy usage early in the development flow has the potential to significantly reduce the overall energy usage of a software system, as it allows developers to make informed design and refactoring decisions before inefficiencies propagate. However, assessing energy usage without repeated profiling and direct measurement is difficult, which limits early reasoning in practice. This study investigates the limits of method-level energy prediction in Java, examining whether static source code metrics complemented with method-level execution time can estimate the energy consumption of Java methods. We profile 2,786 Java methods to extract 33 static features and measure execution time and energy, then train and compare eleven regression models. Our findings show that static source code metrics alone yield poor predictive performance, with average R2 values close to zero. Incorporating execution time as a lightweight dynamic input significantly improves accuracy, raising R2 to as high as 0.46. Execution time, internal method calls, and cyclomatic complexity consistently emerge as the strongest predictors of energy consumption. Keywords: Software energy consumption · Method-level energy estimation · Source code metrics · Machine learning · Java

1

Introduction

Energy consumption has emerged as a critical concern in modern software development, not only in mobile or embedded environments but also in generalpurpose computing. As software systems grow increasingly complex and resourceintensive, their energy footprints become non-trivial, impacting battery life, operational costs, and environmental sustainability [35]. A significant part of the research in this domain relies on empirical measurements, as energy is strongly influenced by the execution environment of the application [10]. These measurements are obtained through repeated executions in controlled environments, often using specialized profiling tools and hardware instrumentation [43]. Although these methods provide precise and reliable energy consumption data, they often require manual setup or hardware access to capture fine-grained data, which limits their routine use in development workflows [18]. Consequently, during refactoring or design, developers typically lack

2

Muhammad Imran, Vincenzo Stoico, and Ivano Malavolta

accessible ways to reason about energy consumption without repeated profiling [39]. The limitations of measurement-based approaches become especially clear when energy profiling is required at fine-grained levels, such as individual methods. Recent studies demonstrate that even small syntactic code changes can introduce measurable variations in energy usage, especially in compiled or performance-sensitive programs [38]. Despite this growing recognition, few studies have systematically modeled energy consumption from static code features like cyclomatic complexity, loop depth, or library usage, especially at the method level. Multiple studies [20, 3] show static features influence energy by shaping control flow, computational intensity, and resource access, highlighting their importance in energy modeling. Most work focuses on coarse-grained estimation (language- or library-level) or hybrid methods requiring execution [38, 3]. This gap is particularly notable in Java, where low-level decisions such as collection types and loop constructs affect energy in subtle ways [38, 31], while higher-level design patterns have been found largely energy-neutral [37]. These observations motivate approaches that support fine-grained energy awareness while reducing reliance on repeated profiling and specialized instrumentation, since energy consumption depends not only on source code but also on its interaction with hardware and runtime characteristics [41], suggesting that combining static and dynamic features may improve prediction accuracy, and at method level, such predictions can directly guide developers toward the specific code units responsible for high energy usage, enabling targeted optimization. The goal of this study is to assess the extent to which static features extracted from Java methods can explain method-level energy consumption, and to identify their limitations. We further investigate whether adding execution time improves predictive performance. Our research methodology involves profiling 2,786 Java methods from 768 files representing 815 programming tasks to collect static features, execution time, and energy measurements. We extract 33 source-level features per method, profile execution time and energy on a fixed testbed, and train eleven regression models through a structured process including feature selection, model comparison, and hyperparameter tuning. Our findings show that static code features alone yield near-zero predictive power (R2 ≈ 0), and that only the inclusion of execution time as a lightweight dynamic input raises R2 to 0.46, indicating that method-level energy is dominated by runtime behavior rather than source structure alone. We provide a publicly available replication package [25], containing the dataset, energy measurements, execution times, static features, training scripts, and complete experimental results.

2

Related Work

Energy Efficiency Recent studies have explored energy efficiency in highlevel languages, showing that alternative compilers such as Codon [45], Pythran, and PyPy consistently outperform CPython in execution time and energy efficiency [4], and that HOPE [1] and Codon demonstrate similar gains on numerical

Static Metrics Are Insufficient: Predicting Java Method Energy

3

benchmarks against C++. While these studies show energy gains through compiler optimization, they focus on coarse-grained program behavior and specific benchmark types or parallel computing use cases. Recent work has also examined fine-grained energy variations caused by structural differences in source code. Stoico et al. [46] demonstrated that small syntactic modifications in Python programs, such as altering list comprehensions or loop constructs, can significantly affect both execution time and energy consumption, depending on how the code is compiled and optimized. Similarly, Cursaru et al. [15] showed that functionally equivalent code generated by different LLM prompts can result in measurable differences in energy usage, driven solely by structural variations. These studies emphasize that source code organization itself can directly influence energy behavior, even though their results are not directly transferable to Java, and motivate the broader question of whether structural source code properties are informative for energy estimation at finer levels of granularity. We investigate this question at the level of individual Java methods using static code features and execution time. Static Code Metrics Several studies have explored static code metrics as predictors of software energy consumption. Kumar et al. [31] showed that Java constructs such as loops, data types, and collections can significantly impact energy usage. Hamza Alvi et al. [3] proposed the MLEE framework, which applies machine learning for method-level energy estimation in Android applications using structural code features under controlled execution scenarios, though its strong predictive performance relies on platform-specific assumptions not directly transferable to general-purpose Java workloads. Akinli [2] further demonstrated the viability of combining code metrics with learning models for energy prediction across benchmarks. Broader perspectives are offered by Kruglov et al. [30], who emphasize the integration of sustainability metrics into software processes, and Schuler et al. [43], who identify the lack of fine-grained static code-based energy models in the current literature. Beyond energy estimation, static metrics have also proven valuable in predicting security vulnerabilities [17], estimating maintenance effort [12], and understanding the energy impact of design decisions such as code smells and refactoring [42]. Closest to our work, Goyal et al. [19] recently proposed EnCoDe, which predicts block-level energy of Python code purely from static AST features (R2 of 0.75), with ground-truth labels obtained via amplified executions of isolated code blocks with fixed inputs. Notably, their ablation shows that complexity metrics alone yield an R2 of 0.067. In contrast, our study examines a broader set of static features including metrics from software performance evaluation, adds execution time as a dynamic feature, targets methods executed within complete Java programs rather than isolated code fragments, and performs a structured comparison of multiple regression models with systematic feature selection and hyperparameter tuning, offering a complete evaluation of ML-based energy estimation at the method level. Machine Learning Models for Prediction While MLEE [3] and Akinli [2] demonstrated the feasibility of ML-based energy estimation at method level, nei-

4

Muhammad Imran, Vincenzo Stoico, and Ivano Malavolta

(a) Main steps of the study.

(b) Profiling using Experiment Runner.

Fig. 1: Overview of the study workflow and profiling setup.

ther performed extensive model comparison, tuning, or feature selection analysis. Kruglov et al. [30] and Schuler et al. [43] also note the growing trend of modelbased estimation, yet few studies systematically compare the performance of different models or assess the impact of tuning and feature selection on prediction accuracy. Our study addresses this gap through a structured comparison of eleven regression models evaluated across multiple feature selection and tuning configurations.

3

Study Design

We define three research questions (RQs) guiding our investigation: ▷ RQ1 : To what extent can method-level energy consumption be predicted from static source code features, and how does predictive performance change when execution time is added? This research question assesses the baseline predictive value of static code features and evaluates the marginal effect of adding execution time as a lightweight dynamic input. Models are trained with default hyperparameters. ▷ RQ2 : What is the effect of feature selection on the performance of energy prediction models? We investigate whether removing less informative features improves generalization and which code characteristics are most predictive of energy usage, offering guidance for developers when dynamic profiling is unavailable. ▷ RQ3 : How does hyperparameter tuning influence model performance for predicting method-level energy usage? We explore whether fine-tuning yields meaningful accuracy gains over defaults, clarifying the relative importance of model optimization versus feature engineering in our prediction setting.

Static Metrics Are Insufficient: Predicting Java Method Energy

5

Our study follows a structured process consisting of three main steps: (i) subject selection, (ii) data preparation, and (iii) model training and tuning, as shown in Figure 1(a). 3.1

Subject Selection

We selected Java implementations from two publicly available repositories: the Computer Language Benchmarks Game (CLBG)3 and Rosetta Code4 . They provide community-contributed implementations of algorithmic tasks across multiple languages, typically self-contained and computationally intensive, making them well suited for controlled energy profiling at method level. For Rosetta Code, we used a curated GitHub snapshot5 organizing 1,228 tasks, of which 1,146 had Java implementations, resulting in 1,790 files across all variants. From CLBG, crawling 10 tasks provided 49 files. We filtered out implementations that: (i) lacked a main method, (ii) required user input or a graphical interface, (iii) contained infinite loops, (iv) had duplicate class names, or (v) could not be compiled due to external dependencies. After filtering 853 Java files corresponding to 812 distinct tasks were retained. 3.2

Data Preparation

Data was collected at method level through two complementary pipelines: static analysis for code features and dynamic profiling for execution time and energy. Static Analysis Following established practices in performance analysis [23], each Java file was parsed using srcML [13] to apply XPath queries. We extracted 33 static features per method covering control flow, complexity, and standard library usage, as summarized in Table 1. Features were guided by prior work on software performance [24] and selected by correlating known static metrics with energy to filter out less informative ones, yielding features for 2,786 methods across the 853 files. Dynamic Profiling To collect execution time and energy consumption data, we followed established guidelines for energy measurement [21, 34] and used Experiment Runner [27] as experiment orchestrator shown in Figure 1(b). For CPU sampling, we used async-profiler 6 to collect method-level execution times, and for energy measurement, we employed JoularJX 7 , which provides method-level energy estimation within the JVM. The 853 Java files were compiled using javac version 18.0.1.1, producing 1,100 .class files. Profiling commands attach both agents to the JVM via a custom wrapper class, LoopRunner, which executes each program’s main method multiple times in a loop. Since both async-profiler and JoularJX rely on sampling, https://benchmarksgame-team.pages.debian.net/benchmarksgame/index.html https://rosettacode.org/wiki/Rosetta_Code 5 https://github.com/acmeism/RosettaCodeData 6 https://github.com/async-profiler/async-profiler 7 https://www.noureddine.org/research/joular/joularjx 3 4

6

Muhammad Imran, Vincenzo Stoico, and Ivano Malavolta Table 1: Collected source code features.

(iii) standard Java APIs

(ii) language feature

(i)meta info

Level/ Category Feature Name method

Description

#methodLOC

Lines of code of the method

#nameLen

method name length

methodScope

access specifier of the method

isOverloaded if the method is overloaded #if no. of if conditions #switch no. of switch statements #case no. of case statements #for no. of for loops #while no. of while loops #do no. of doWhile loops #nestedLoops no. of nested loops (arbitrary depth) control flow #methodCalls no. of methods called and data #internalCalls no. of internal methods called #externalCalls no. of external methods called #return no. of return statements #throw no. of throw statements #catch no. of catch statements #cyclo cyclomatic complexity #vars no. of the variables declared utility java.util Utility classes in Java. java.lang Core Java classes & Multithreading os and concurrency java.lang.management Management interfaces for Java. java.util.concurrent Advanced concurrency utilities. java.io Data streams based I/O. java.nio New I/O for scalable I/O operations. java.nio.channels Channels for non blocking I/O. io java.nio.file NIO based File I/O enhancements. java.nio.charset Classes for encoding and decoding. java.net Networking and communication. javax.net.ssl For secure network communication. java.util.regex Regex for pattern matching & Strings. strings java.text Text parsing and formatting classes. math java.math Mathematical utilities.

repeating executions increases the likelihood of capturing short-lived methods that may not be observed in a single run. We set the repetition count to 20, which captured energy measurements for ∼48% more methods and executiontime data for ∼14% more methods compared to a single run. Input values for CLBG tasks were taken from the task pages and Rosetta Code inputs were embedded in the implementations. We selected JoularJX as the energy profiler because it provides method-level energy measurements directly within the JVM through agent-based instrumentation, correlating runtime method execution with CPU utilization and power readings to attribute total JVM energy consumption to individual methods [36]. Other approaches, including hardware counters such as Intel’s RAPL [28] and tools such as CodeCarbon [33], PowerAPI [16], and RJoules [11], produce system or process level estimates rather than method-level attribution. JoularJX instead remains lightweight, cross-platform, and compatible with async-profiler for synchronized CPU and energy traces. Prior to profiling, a warm-up phase (repeated Fibonacci execution) stabilized JVM state (JIT activation and thermal steady state). Each profiling iteration was triggered via HTTP POST to a Flask server on the testbed, followed by a 30-second cool-down period as a standard

Static Metrics Are Insufficient: Predicting Java Method Energy

7

practice8 for preventing heat accumulation across sequential runs. Both profilers were configured at a 1 ms sampling interval to match JoularJX’s minimum resolution9 . Profiler outputs (.collapsed for async-profiler, .csv for JoularJX ) were parsed to extract method-level metrics. Execution times were recovered for 1,980 methods and energy values for 1,103 methods. Since async-profiler samples via CPU events while JoularJX operates at fixed temporal intervals [9], profiler coverage is only partially overlapping, reducing the number of methods with complete feature pairs without affecting measurement validity. To mitigate bias, we retained only the intersection of methods reported by both profilers for model training. 3.3 Model Training and Tuning Our approach was inspired by previous studies on software performance [24, 32] and energy estimation [2], using regression models to predict energy from source code characteristics. Table 2 lists the eleven regression models selected based on: (i) prior use in software engineering analytics [24, 32, 2], (ii) flexibility to capture linear and non-linear relationships, and (iii) availability in scikit-learn10 for reproducibility. The process follows three steps aligned with RQ1–RQ3: base model training, feature selection, and hyperparameter tuning. Table 2: ML models used in this study. Model Acronym Algorithm Random Forest RF Ensemble Gradient Boosting GB Ensemble-Boosting ADA Boosting ADA Ensemble-Boosting Hist Gradient Boosting HGB Ensemble-Boosting Lasso Regression Lasso-R Linear k-Nearest Neighbor kNN Instance-based Ridge Regression Ridge-R Linear Support Vector Machine SVM Kernel-based Linear Regression LR Linear Multi-Layer Perceptron MLP Neural Network Decision Tree DT Decision Tree

Data Pre-processing From the initial 2,786 methods, matching with profiler outputs (JoularJX and async-profiler) resulted in 902 methods with complete static and dynamic data. After removing methods with zero energy consumption which are likely trivial code paths that would distort training, we got 265 methods remaining. To deal with the long-tailed distributions of both energy and execution time values, we applied a natural logarithmic transformation, which mitigated skewness and made the variables more suitable for regression modeling. The categorical methodScope feature was one-hot encoded to produce a fully numeric feature matrix. https://luiscruz.github.io/2021/10/10/scientific-guide.html github.com/joular/joularjx/blob/develop/config.properties 10 https://scikit-learn.org/ 8 9

8

Muhammad Imran, Vincenzo Stoico, and Ivano Malavolta

Model Training We define a supervised learning task where each instance corresponds to a Java method characterized by static features (e.g., lines of code, number of loops), and the target variable is the dynamic energy measure obtained through our profiling setup. The training set includes static features and execution time in milliseconds as predictors and energy consumption (measured in Joules) as the target variable. We apply 5-fold cross-validation (rather than 10-fold, to ensure sufficiently large validation samples given our dataset size of 265 methods) to reduce variance due to sampling, using an 80/20 split repeated five times across shuffled partitions. Models are trained with default hyperparameters without feature pre-processing, as this initial step establishes the baseline performance evaluated in RQ1. Feature Selection and Configuration Comparison To address RQ2, we applied seven feature pre-processing techniques: RFECV [22], AutoSpearman [26], SelectKBest [40] (k ∈ {10, 20, 30}), and VarianceThreshold [44]. RFECV eliminates features iteratively based on model feedback; AutoSpearman removes multicollinear features by thresholding pairwise Spearman correlation. Evaluating all model × feature-selection combinations yields 77 configurations (11 models × 7 variants). Configurations are compared using R2 and the five top-performing configurations are carried forward for hyperparameter tuning. Hyperparameter Tuning To address RQ3, we applied RandomizedSearchCV to the top five configurations using model-specific parameter grids available in the replication package [25]. Random search is more efficient than grid or manual search for finding optimal hyperparameters [7]. The tuning objective is to maximize R2 . Performance Evaluation We adopt four standard regression metrics, widely used in software effort estimation [6], defect prediction [5], and energy-aware analytics [2, 30, 3]. We use R2 as the primary indicator of overall performance and for selecting the best model configurations, as it captures how effectively the features explain variance in energy usage. Mean Absolute Error (MAE), Mean Squared Error (MSE), and Mean Absolute Percentage Error (MAPE) complement this by characterizing the magnitude and scale of prediction errors.

4

Results

4.1

RQ1 : Predictive performance for energy

Figure 2 summarizes the baseline results, showing that the predictive performance of all regression models trained on static features and execution time remains limited. RF achieves the best performance with an R2 of 0.45, an M SE of 7.15, an M AE of 2.02, and a M AP E of 1.75, offering strong interpretability through its feature importance estimates. At the other extreme, DT performs worst with an R2 of only 0.05 and a M AP E exceeding 2.8, indicating overfitting and poor generalization. Overall, all models only partially explain the variability in energy consumption: the best R2 remains below 0.5, M SE ranges from 7 to 12, and M AP E stays mostly below 2%, indicating that predictions are proportionally close to actual values even when absolute errors are larger.

Static Metrics Are Insufficient: Predicting Java Method Energy

9

Record · ID 346514 · SHA-256 57ca7a2af96c9ff7
Retrieved via Conceptio — every document is proof-bundled with source, license, and retrieval metadata.