# Automatically Injecting Robustness Statements into Distributed Applications
## 6 Discussion  
To evaluate the effectiveness of our approach, the transformed version was compiled and executed successfully. While the refactored version is robust against network delays and intermittent malfunctioning, it also performs better in terms of execution time. Across all four benchmarked methods, the average speed-up was 14.42%. The method getUserForAuthor() showed the highest improvement at 21.83%, while extractMostReviewedAuthor() exhibited the lowest at 11.08%. The performance of the parallel version and the resulting speed-up are primarily influenced by the workload balance between the parallel paths. Maximum gain occurs when both paths execute with minimal time discrepancy, enabling concurrent execution without idle time.  
The benchmarks revealed varying speed-up results. The method getUserForAuthor() demonstrated high performance gain as the parallel threads exhibited similar execution times. Conversely, methods yielding 11.08%, 11.97%, and 12.82% speed-ups showed greater execution time discrepancies between parallel paths. Nonetheless, our transformations effectively enhanced performance across these benchmarks. Notably, getUserForAuthor() required longer execution times compared to other benchmarks due to its handling of larger datasets, necessitating greater computational effort, which in turn led to higher performance gains. The first three benchmarks (see Tables 1-3) exhibited some negative speed-ups, indicating that sequential execution achieved lower overall times. This may be attributed to factors such as thread scheduling, cache effects, and load balancing in parallel execution environments. In particular, the management of multiple threads can introduce synchronization delays, while frequent cache misses and the imbalanced distribution of tasks across threads can degrade performance, offsetting the benefits of parallelism.  
When occasional network delays or failures occur, while the original version simply hangs or terminates abruptly, our transformed version of the application recovers from the faults, given that the network communication will be restored within the interval set in the proper RetryPolicy object.  
Table 5 shows the significant impact of a communication delay. By default, if a Java RMI call fails, it does not automatically initiate a retry; rather, it throws a RemoteException (or a related exception depending on the issue), causing the operation to terminate unless properly handled. When the underlying socket timeout was set to 2 s, the RMI call would experience a crash each time the network communication delay exceeds 2 s. In contrast, our proposed transformation enhances the robustness and resilience by employing a retry policy, which make the running application recover from the timeout and remain operational despite increasing communication delays. As shown in Listing 3, this policy employs an exponential backoff mechanism with a maximum timeout of 30 s and allows up to 20 retries, thereby ensuring a robust and effective failure management.  
Our approach was designed to enhance both the robustness of network communication and correct execution, while also aiming at achieving some performance gains. However, there are inherent limitations, particularly when relying solely on static code analysis.  
Static analysis cannot reliably predict the specific method executed at runtime, especially in cases involving polymorphism. In these scenarios, we adopt a cautious approach for safety reasons then assume maximum data dependencies among the methods and potentially miss opportunities for parallel execution. Moreover, when code contains multiple references to objects of the same type, static analysis struggles to distinguish between instances, particularly when variables conditionally assign different references. This can lead to missed opportunities for parallel execution on distinct objects.