Skip to content

Commit

Permalink
v1.4.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Morten Haraldsen committed Mar 24, 2024
1 parent cd0f474 commit 64bfbbb
Show file tree
Hide file tree
Showing 9 changed files with 110 additions and 34 deletions.
16 changes: 8 additions & 8 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
<groupId>com.ethlo.time</groupId>
<artifactId>chronograph</artifactId>
<name>Chronograph</name>
<description>Easy to use timer allowing accurate measurement of elapsed time</description>
<version>1.3.0-SNAPSHOT</version>
<description>Easy-to-use stopwatch for task performance statistics</description>
<version>1.4.0</version>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
Expand Down Expand Up @@ -36,7 +36,7 @@
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.7</version>
<version>0.8.11</version>
<executions>
<execution>
<id>prepare-agent</id>
Expand Down Expand Up @@ -98,7 +98,7 @@
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<version>1.6.8</version>
<version>1.6.13</version>
<extensions>true</extensions>
<configuration>
<serverId>sonatype-nexus-staging</serverId>
Expand All @@ -109,19 +109,19 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-gpg-plugin</artifactId>
<version>3.0.1</version>
<version>1.6</version>
<executions>
<execution>
<id>sign-artifacts</id>
<phase>verify</phase>
<goals>
<goal>sign</goal>
</goals>
<configuration>
<executable>gpg</executable>
</configuration>
</execution>
</executions>
<configuration>
<useAgent>false</useAgent>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
Expand Down
48 changes: 37 additions & 11 deletions src/main/java/com/ethlo/time/ChronographData.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,13 @@
*/

import java.time.Duration;
import java.util.LinkedList;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import com.ethlo.time.statistics.DurationPerformanceStatistics;
import com.ethlo.time.statistics.ThroughputPerformanceStatistics;

public class ChronographData
{
Expand All @@ -39,20 +44,23 @@ public ChronographData(final String name, final List<TaskPerformanceStatistics>

public static ChronographData combine(final String name, final List<Chronograph> toCombine)
{
final List<TaskPerformanceStatistics> all = new LinkedList<>();
for (Chronograph c : toCombine)
if (toCombine.isEmpty())
{
final ChronographData taskData = c.getTaskData();
final String runName = taskData.name;

for (TaskPerformanceStatistics taskStats : taskData.taskStatistics)
throw new IllegalArgumentException("No results to combine");
}
if (toCombine.size() == 1)
{
return toCombine.get(0).getTaskData();
}
else
{
ChronographData last = toCombine.get(0).getTaskData();
for (int i = 1; i < toCombine.size(); i++)
{
final String fullName = runName != null && runName.length() > 0 ? (runName + " - " + taskStats.getName()) : taskStats.getName();
all.add(new TaskPerformanceStatistics(fullName, taskStats.getSampleSize(), taskStats.getDurationStatistics(), taskStats.getThroughputStatistics()));
last = last.merge(name, toCombine.get(i).getTaskData());
}
return last;
}
final Duration total = toCombine.stream().map(Chronograph::getTaskData).map(ChronographData::getTotalTime).reduce(Duration.ZERO, Duration::plus);
return new ChronographData(name, all, total);
}

public String getName()
Expand All @@ -74,4 +82,22 @@ public boolean isEmpty()
{
return this.taskStatistics.isEmpty();
}

public ChronographData merge(String chronographName, ChronographData chronographData)
{
final Map<String, TaskPerformanceStatistics> joined = new LinkedHashMap<>(Math.max(this.taskStatistics.size(), chronographData.taskStatistics.size()));
this.taskStatistics.forEach(t -> joined.put(t.getName(), t));
chronographData.taskStatistics.forEach(t -> joined.compute(t.getName(), (k, v) ->
{
if (v != null)
{
final long sampleSize = v.getSampleSize() + t.getSampleSize();
final DurationPerformanceStatistics durationStatistics = ((DurationPerformanceStatistics) t.getDurationStatistics()).merge((DurationPerformanceStatistics) v.getDurationStatistics());
final ThroughputPerformanceStatistics throughputStatistics = ((ThroughputPerformanceStatistics) t.getThroughputStatistics()).merge((ThroughputPerformanceStatistics) v.getThroughputStatistics());
return new TaskPerformanceStatistics(k, sampleSize, durationStatistics, throughputStatistics);
}
return t;
}));
return new ChronographData(chronographName, new ArrayList<>(joined.values()), Duration.ofNanos(joined.values().stream().mapToLong(t -> t.getDurationStatistics().getElapsedTotal().toNanos()).sum()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,9 @@ public Duration getStandardDeviation()
}
return Duration.ofNanos(MathUtil.sqrt(sd).longValue());
}

public DurationPerformanceStatistics merge(final DurationPerformanceStatistics other)
{
return new DurationPerformanceStatistics(this.collectionStatistics.merge(other.collectionStatistics), totalInvocations + other.totalInvocations, elapsedTotal.plus(other.elapsedTotal));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,9 @@ public Double getStandardDeviation()
}
return MathUtil.sqrt(sd).doubleValue();
}

public ThroughputPerformanceStatistics merge(final ThroughputPerformanceStatistics other)
{
return new ThroughputPerformanceStatistics(this.collectionStatistics.merge(other.collectionStatistics), totalInvocations + other.totalInvocations, elapsedTotal.plus(other.elapsedTotal));
}
}
8 changes: 8 additions & 0 deletions src/main/java/com/ethlo/util/IndexedCollectionStatistics.java
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,12 @@ public IndexedCollection<Long> getList()
{
return list;
}

public IndexedCollectionStatistics merge(IndexedCollectionStatistics other)
{
final LongList list = new LongList((Math.max(10, this.list.size() + other.list.size()) / 10));
this.list.forEach(list::add);
other.list.forEach(list::add);
return new IndexedCollectionStatistics(list);
}
}
4 changes: 4 additions & 0 deletions src/main/java/com/ethlo/util/LongList.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ public LongList()

public LongList(int blockSize)
{
if (blockSize < 1)
{
throw new IllegalArgumentException("blockSize cannot be less than 1");
}
this.blockSize = blockSize;
}

Expand Down
18 changes: 11 additions & 7 deletions src/main/java/com/ethlo/util/MathUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,33 @@
* #L%
*/

import static java.math.BigDecimal.ROUND_HALF_UP;

import java.math.BigDecimal;
import java.math.RoundingMode;

public class MathUtil
{
private static final BigDecimal TWO = BigDecimal.valueOf(2);

public static BigDecimal sqrt(BigDecimal value)
{
return sqrt(value, 10);
}

public static BigDecimal sqrt(BigDecimal value, final int SCALE)
{
BigDecimal TWO = BigDecimal.valueOf(2);
if (value.compareTo(BigDecimal.ZERO) == 0)
{
return value;
}

BigDecimal x0 = BigDecimal.ZERO;
BigDecimal x1 = new BigDecimal(Math.sqrt(value.doubleValue()));
BigDecimal x1 = BigDecimal.valueOf(Math.sqrt(value.doubleValue()));
while (!x0.equals(x1))
{
x0 = x1;
x1 = value.divide(x0, SCALE, ROUND_HALF_UP);
x1 = value.divide(x0, SCALE, RoundingMode.HALF_UP);
x1 = x1.add(x0);
x1 = x1.divide(TWO, SCALE, ROUND_HALF_UP);

x1 = x1.divide(TWO, SCALE, RoundingMode.HALF_UP);
}
return x1;
}
Expand Down
22 changes: 22 additions & 0 deletions src/test/java/com/ethlo/time/ChronographTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ethlo.ascii.TableTheme;
import com.ethlo.util.SleepUtil;

public class ChronographTest
Expand Down Expand Up @@ -242,4 +243,25 @@ public void testGetAverageForNonStoppedTask()
chronograph.start(taskName);
assertThat(chronograph.getTasks(taskName).getDurationStatistics().getAverage()).isEqualTo(Duration.ZERO);
}

@Test
void testMergeResults()
{
final Chronograph chronograph1 = Chronograph.create();
chronograph1.start(taskName);

final Chronograph chronograph2 = Chronograph.create();
chronograph2.start(taskName);

chronograph1.stop();
chronograph2.stop();
final ChronographData merged = chronograph2.getTaskData().merge("merged", chronograph1.getTaskData());

System.out.println(Report.prettyPrint(merged,
OutputConfig.EXTENDED.mode(PresentationMode.THROUGHPUT).benchmarkMode(true),
TableTheme.RED_HERRING
));

assertThat(true).isTrue();
}
}
18 changes: 10 additions & 8 deletions src/test/java/com/ethlo/util/ListPerformanceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,9 @@ private Chronograph performAddBenchmark(final int runs, final int size)

for (int i = 0; i < runs; i++)
{
c.timedFunction("LinkedList", this::addLinkedList, size);
c.timedFunction("ArrayList", this::addArrayList, size);
c.timedFunction("IndexedCollection", this::addLongList, size);
c.timedFunction("LinkedList - Add", this::addLinkedList, size);
c.timedFunction("ArrayList - Add", this::addArrayList, size);
c.timedFunction("IndexedCollection - Add", this::addLongList, size);
}
return c;
}
Expand Down Expand Up @@ -154,9 +154,9 @@ private Chronograph performSortBenchmark(final int runs, final int size)
final List<Long> linkedList = addLinkedList(size);
final List<Long> arrayList = addArrayList(size);

c.timed("LinkedList", () -> linkedList.sort(Comparator.naturalOrder()));
c.timed("Arraylist", () -> arrayList.sort(Comparator.naturalOrder()));
c.timed("IndexedCollection", longList::sort);
c.timed("LinkedList - Sort", () -> linkedList.sort(Comparator.naturalOrder()));
c.timed("ArrayList - Sort", () -> arrayList.sort(Comparator.naturalOrder()));
c.timed("IndexedCollection - Sort", longList::sort);
}
return c;
}
Expand All @@ -165,8 +165,10 @@ private Chronograph performSortBenchmark(final int runs, final int size)
void testCombinedPerformanceTable()
{
final Chronograph a = performAddBenchmark(20, 10_000);
final Chronograph b = performSortBenchmark(10, 10_000);
final ChronographData combined = ChronographData.combine("Combined", Arrays.asList(a, b));
final Chronograph b = performAddBenchmark(10, 10_000);
final Chronograph c = performAddBenchmark(5, 10_000);
final Chronograph d = performSortBenchmark(8, 10_000);
final ChronographData combined = ChronographData.combine("Combined", Arrays.asList(a, b, c, d));

System.out.println(Report.prettyPrint(combined,
OutputConfig.EXTENDED.mode(PresentationMode.THROUGHPUT).benchmarkMode(true),
Expand Down

0 comments on commit 64bfbbb

Please sign in to comment.