HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Generic Timing Class - Follow Up

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
genericclassfollowtiming

Problem

I wrote a class which can time and compare functions.

I already posted it here once before, and got great suggestions from @rolfl, which I have added to my code.

  • my original question can be found here (example usages can be found there as well)



  • the formating class I use can be found here



As before, I'm interested in any and all suggestions you might have (for example code design, accuracy of measurement, usability, naming, commenting, etc).

The revised Timing code:

```
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.IntFunction;

/**
* A timing class.
*
* Timings are run in chunks. For each chunk, the input is gathered before-hand.
*/
public class Timing {

private List functionsToTime;

/**
* amount of chunks to run.
*/
private int amountChunks = 1_000;

/**
* amount of runs per chunk.
*/
private int amountRunsPerChunk = 1_000;

public Timing() {
functionsToTime = new ArrayList<>();
}

/**
* adds a new function which will be timed.
*
* @param return type of functionToTime (irrelevant)
* @param input type of functionToTime (same as return type of
* inputConverter)
* @param functionToTime a function expecting input of type T, returning
* output of any type (R)
* @param inputConverter converts the loop variable to type T and passes it
* to functionToTime
* @param name name of the function (used for output)
*/
public void add(Function functionToTime, IntFunction inputConverter, String name) {
functionsToTime.add(new TimingObject(functionToTime, inputConverter, name));
}

/**
* sets how many chunks should be run.
*
* The total amount of how often the given functions should be run when
timed is amountChunks amountRunsPerChunk.
*
* @param amountChunks amountCh

Solution

Make more fields immutable

There are several fields that could have been final, for example these:

public class Timing {
    private List functionsToTime;
    // ...

private class TimingObject {
    private Function function;
    private IntFunction inputConverter;
    private String name;
    private List times;
    // ...


Make everything final that you can.

Use more for-each loops

Somewhat oddly, you left a few old-fashioned for (;;)style loops that could be rewritten using for-each, for example in TimingObject.addTimeChunk:

for (int i = 0; i < timeChunk.length; i++) {
    times.add(timeChunk[i]);
}


And in Statistics:

for (int i = 0; i < length; i++) {
    mean += list.get(i) / (double) length;
}


Simpler initialization

If you move the initialization of Timing.functionsToTime to declaration,
you can get rid of the constructor, making the code slightly shorter.

private List functionsToTime = new ArrayList<>();


Raw types

There is a raw ArrayList in Timing.time:

ArrayList input = new ArrayList<>();
for (int runs = 0; runs < amountRunsPerChunk; runs++) {
    input.add(timingObject.inputConverter.apply((chunks * amountRunsPerChunk) + runs));
}


It would be better to use ArrayList instead, or there might be an even better way.

Redundant parentheses

There are a couple parentheses that are really redundant, for example:

list.subList(0, (REMOVE_WORST_PERCENT * originalSize / 100)).clear();

int rank = (int) Math.ceil((percentile / 100) * list.size());

Code Snippets

public class Timing {
    private List<TimingObject> functionsToTime;
    // ...

private class TimingObject {
    private Function function;
    private IntFunction inputConverter;
    private String name;
    private List<Long> times;
    // ...
for (int i = 0; i < timeChunk.length; i++) {
    times.add(timeChunk[i]);
}
for (int i = 0; i < length; i++) {
    mean += list.get(i) / (double) length;
}
private List<TimingObject> functionsToTime = new ArrayList<>();
ArrayList input = new ArrayList<>();
for (int runs = 0; runs < amountRunsPerChunk; runs++) {
    input.add(timingObject.inputConverter.apply((chunks * amountRunsPerChunk) + runs));
}

Context

StackExchange Code Review Q#64563, answer score: 2

Revisions (0)

No revisions yet.