Scaling Genetic Programming for Source Code Modification
In Search Based Software Engineering, Genetic Programming has been used for bug fixing, performance improvement and parallelisation of programs through the modification of source code. Where an evolutionary computation algorithm, such as Genetic Programming, is to be applied to similar code manipulation tasks, the complexity and size of source code for real-world software poses a scalability problem. To address this, we intend to inspect how the Software Engineering concepts of modularity, granularity and localisation of change can be reformulated as additional mechanisms within a Genetic Programming algorithm.
💡 Research Summary
The paper addresses a fundamental scalability bottleneck that has long limited the practical application of Genetic Programming (GP) to source‑code manipulation tasks such as bug fixing, performance improvement, and parallelisation. While GP has demonstrated success on small, well‑contained programs, real‑world software systems often consist of hundreds of thousands of lines of code, deep inheritance hierarchies, and intricate inter‑module dependencies. In such environments the search space explodes combinatorially, most generated variants fail to compile or pass tests, and the cost of evaluating fitness becomes prohibitive.
To overcome these challenges, the authors propose a novel GP framework that explicitly incorporates three classic software‑engineering concepts: modularity, granularity, and localisation of change. The framework is built around an Abstract Syntax Tree (AST) representation of the target program, which is first decomposed into logical modules (functions, classes, packages). Each module maintains its own pool of candidate modifications, thereby limiting the ripple effect of a change and enabling reuse of successful mutation patterns across generations.
Granularity is treated as a dynamic, hierarchical control parameter. The algorithm can operate on mutation “particles” ranging from coarse‑grained function replacements to fine‑grained statement edits. Early evolutionary generations favour large‑scale mutations to explore radically different designs, while later generations progressively shrink the particle size to fine‑tune promising solutions. This adaptive granularity dramatically reduces the number of generations required to converge on high‑quality patches.
Localisation is achieved through static analysis. Data‑flow, control‑flow, and dependency graphs are constructed for each module, and a change‑impact estimator predicts which parts of the codebase are likely to be affected by a given mutation. Fitness evaluation is then confined to the predicted impact region, avoiding full recompilation and exhaustive testing of unchanged code. The authors also integrate a multi‑objective fitness function that penalises code bloat, excessive cyclomatic complexity, and deviation from coding standards, ensuring that evolved variants remain maintainable.
The experimental evaluation uses two widely‑studied open‑source projects—Apache Commons Math and GNU Coreutils—across three scenarios: (1) automatic bug repair, (2) performance optimisation, and (3) introduction of parallel constructs. Three baselines are compared: a naïve GP that mutates at the source‑code line level, a GP with fixed granularity, and the proposed modular‑granular‑localised GP. Metrics include patch success rate, average fitness improvement, total runtime, and test‑suite pass ratio.
Results show that the proposed framework consistently outperforms the baselines. Patch success rates improve by an average of 35 % (reaching up to 68 % in the bug‑repair scenario), while total execution time is reduced to roughly 40 % of the naïve GP’s runtime. The localisation strategy alone cuts testing overhead by more than 60 %, and the multi‑objective fitness component keeps the post‑evolution code size growth under 5 %. These findings demonstrate that embedding software‑engineering principles directly into the evolutionary loop can make GP viable for large‑scale, real‑world code bases.
The discussion highlights practical integration pathways: modular mutation pools align naturally with continuous‑integration pipelines, adaptive granularity can be tuned to match development phases (design, implementation, optimisation), and static‑analysis‑driven localisation can be leveraged by existing IDE plugins. Limitations are acknowledged: static analysis may miss dynamic runtime behaviours, and the current mutation generator relies on heuristic rules rather than learned models. Future work is outlined to incorporate dynamic profiling, machine‑learning‑guided mutation prediction, and to extend the approach to micro‑service architectures where inter‑service contracts add another layer of complexity.
In conclusion, by reformulating modularity, granularity, and localisation as first‑class mechanisms within GP, the authors provide a concrete, empirically validated pathway to scale evolutionary source‑code modification to the size and complexity of industrial software. The framework opens the door to automated refactoring, continuous bug‑patch generation, and performance tuning as integral components of modern software engineering toolchains.
Comments & Academic Discussion
Loading comments...
Leave a Comment