Overhead of iterating over list in Java

Viewed 50

I have a REST API that fetches a list of entities that is then mapped to DTOs. The requests take quite a lot of time because for 10 fetched entities it's about 1.5seconds. The query to the DB seems OK - it takes about 100ms.

I found that this one piece of code during the mapping entitiy->DTO phase takes about 80% of the time:

Map<String, List<DailyTimeDTO>> dailyTimesGroupedByClientStream = timesheetReport.getDailyTimes()
                .stream()
                .filter(dailyTime -> dailyTime.getWorkTime() != null)
                .map(DailyTimeDTO::create)
                .collect(Collectors.groupingBy(DailyTimeDTO::getClient));

With about 30-40 DailyTime objects it takes 80-100 ms and it is ran for each entity while mapping so when mapping 10 entities the request takes about 1.5 seconds and for 100 entities it takes a whole lot more.

I tried implementing it without the stream but it didn't really help (as below). I tried debugging what takes so much time (using the System.nanoTime() as below) but each iteration of the loop takes about 5 microseconds (so 0.005 ms). But the whole loop takes about 80-100 ms. So where does so much more time get lost? Is it the overhead of iterating over a list multiple times? Is there something I can do about besides figuring out a different way to perform this mapping?

        dailyTimes.forEach( dailyTime -> {
            long startTime = System.nanoTime();

            if (dailyTime == null || dailyTime.getWorkTime() == null) return;

            DailyTimeDTO dailyTimeDTO = DailyTimeDTO.create(dailyTime);
            map.add(dailyTimeDTO.getClient(), dailyTimeDTO);

            log.info("Iteration full {}", (System.nanoTime() - startTime) / 1000);
        });

The DailyTimeDTO::create is nothing special:

   public static DailyTimeDTO create(DailyTime dailyTime) {
      return DailyTimeDTO.builder()
              .client(dailyTime.getClient() == null ? "" : dailyTime.getClient().getClientName())
              .project(dailyTime.getProject() == null ? "" : dailyTime.getProject().getProjectName())
              .hours(dailyTime.getWorkTime())
              .build();
   }
0 Answers
Related