aixigo / sonarqube-java-energyimpact-plugin

SonarQube plugin to analyze Java code patterns and to recommend alternatives with less energy consumption
GNU Lesser General Public License v3.0
3 stars 0 forks source link

Apply CT+ Approach to JAX-RS Based Applications #1

Open schrieveslaach opened 1 year ago

schrieveslaach commented 1 year ago

Unfortunately, the current implementation of CT+ (the tool that recommends energy-efficient Java collection types) does not support dependency injection patterns and therefore it is unsuitable to be used in the context of JAX-RS applications. For example, many micro-services a.k.a. self contained systems in the wild may rely on following class/dependency injection structure.

dia

As CT+ is unable to analyze these patterns, a great potential of energy savings is being left untapped.

Our company creates many HTTP backends that rely on such patterns and based on some internal testing there is a lot of potential to reduce the energy consumption of GET list resources (you find some list resource demonstration here). For example, it could make a difference if the JSON serializer iterates over a FastList or ArrayList to generate JSON.

This issue is a tracking issue for collecting ideas and PRs to provide support for analyzing dependency-injection-based JAX-RS applications through the SonarQube plugin.

schrieveslaach commented 1 year ago

I performed a test with following JAX-RS resource (based on the Quarkus JSON quick start guide):

@Path("/hello")
public class GreetingResource {

   public static List<Fruit> FRUITS;

   static {
      FRUITS = (List<Fruit>) IntStream.rangeClosed( 1, 500 )
         .mapToObj(i -> new Fruit( "fruit-" + i, "fruit description " + i ) )
         .collect( Collectors.toList() );
   }

    @GET
    @Produces( MediaType.APPLICATION_JSON )
    public List<Fruit> fruits() {
       return FRUITS;
    }
}

I measured the energy consumption with the Intel Power Gadget and ran 20,000 HTTP request against it. Then I repeated the measure while changing java.util.stream.Collectors.toList() to Eclipse's Collections [org.eclipse.collections.impl.collector.Collectors2.toList()](https://eclipse.dev/collections/javadoc/11.1.0/org/eclipse/collections/impl/collector/Collectors2.html#toList()) and [org.eclipse.collections.impl.collector.Collectors2.toImmutableList()](https://eclipse.dev/collections/javadoc/11.1.0/org/eclipse/collections/impl/collector/Collectors2.html#toImmutableList()).

Here are the plotted results:

image

We can observe that org.eclipse.collections.impl.collector.Collectors2.toList() seems to have a higher CPU energy consumption in the beginning but energy consumption reduced in the middle of the test. This version also served the 20,000 requests as the fastest. But in summary the sum of energy consumption was the highest.

Clearly, there is a influence but the testing method wasn't yet accurate and therefore, might lead into the wrong direction. Therefore, I think it is best to add some systematic measuring to the project. The results of the measuring will be incorporated into the rules, provided by this project.