jqwik-team / jqwik

Property-Based Testing on the JUnit Platform
http://jqwik.net
Eclipse Public License 2.0
578 stars 64 forks source link

Improved performance of @UniqueElements(by=NOT_SET)` #491

Closed DirkToewe closed 1 year ago

DirkToewe commented 1 year ago

Overview

This PR aims at significantly improving the performance of @UniqueElements(by=NOT_SET), mainly by replacing calls to uniqueElements(x->x) by uniqueElements() wherever possible.

Details

If we look at the following two property tests:

@PropertyDefaults( tries = 100_000 )
public class UniqueElementsTest
{
  @Property void testA( @ForAll @UniqueElements int[] a ) {
    Arrays.sort(a);
    for( int i=1; i < a.length; i++ )
      assert a[i-1] <= a[i];
  }

  @Provide Arbitrary<int[]> arrays() {
    return Arbitraries.integers().array(int[].class).uniqueElements();
  }

  @Property void testB( @ForAll("arrays") int[] a ) {
    Arrays.sort(a);
    for( int i=1; i < a.length; i++ )
      assert a[i-1] <= a[i];
  }
}

On my machine, it takes 20 seconds for testA to finish while testB only takes 2 seconds. The problem becomes much more emphasized with larger array sizes.


I hereby agree to the terms of the jqwik Contributor Agreement.

jlink commented 1 year ago

@DirkToewe As soon as you deem it ready, just rebase it, so that I can merge it.

DirkToewe commented 1 year ago

I did a soft reset and re-committed the changes. All merge conflicts should be gone now.

The PR now also includes the change to FeatureExtractor::areUnique suggested by @vlsi. It felt like it fits the theme of the PR. I hope that's okay.

jlink commented 1 year ago

Published in 1.7.4-SNAPSHOT