Skip to content

Commit e897fb4

Browse files
committed
move sieve tests to test scope, new unit tests
1 parent ec09c70 commit e897fb4

File tree

6 files changed

+166
-86
lines changed

6 files changed

+166
-86
lines changed

src/main/java/de/tilman_neumann/jml/primes/exact/SegmentedSieve.java

-23
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,14 @@
1313
*/
1414
package de.tilman_neumann.jml.primes.exact;
1515

16-
import org.apache.logging.log4j.Logger;
17-
import org.apache.logging.log4j.LogManager;
18-
1916
import de.tilman_neumann.jml.primes.bounds.PrimeCountUpperBounds;
20-
import de.tilman_neumann.util.ConfigUtil;
2117

2218
/**
2319
* Segmented sieve of Eratosthenes based on Kim Walisch's implementation at http://primesieve.org/segmented_sieve.html
2420
*
2521
* @author Tilman Neumann
2622
*/
2723
public class SegmentedSieve {
28-
private static final Logger LOG = LogManager.getLogger(SegmentedSieve.class);
29-
3024
private SieveCallback clientCallback;
3125

3226
public SegmentedSieve(SieveCallback clientCallback) {
@@ -107,21 +101,4 @@ public void sieve(long limit) {
107101
n = nn+low;
108102
}
109103
}
110-
111-
/**
112-
* Test performance without load caused by processPrime().
113-
* @param args ignored
114-
*/
115-
public static void main(String[] args) {
116-
ConfigUtil.initProject();
117-
long limit = 1000000;
118-
while (true) {
119-
long start = System.nanoTime();
120-
CountingCallback callback = new CountingCallback(); // initialize count=0 for each limit
121-
SegmentedSieve sieve = new SegmentedSieve(callback);
122-
sieve.sieve(limit);
123-
LOG.info("Sieving x <= " + limit + " found " + callback.getCount() + " primes in " + ((System.nanoTime()-start) / 1000000) + " ms");
124-
limit *=10;
125-
}
126-
}
127104
}

src/main/java/de/tilman_neumann/jml/primes/exact/SimpleSieve.java

-24
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,13 @@
1313
*/
1414
package de.tilman_neumann.jml.primes.exact;
1515

16-
import org.apache.logging.log4j.Logger;
17-
import org.apache.logging.log4j.LogManager;
18-
19-
import de.tilman_neumann.util.ConfigUtil;
20-
2116
/**
2217
* Monolithic sieve of Eratosthenes, working only for limits < Integer.MAX_VALUE = 2^31 - 1.
2318
* Used for quality tests only.
2419
*
2520
* @author Tilman Neumann
2621
*/
2722
public class SimpleSieve {
28-
private static final Logger LOG = LogManager.getLogger(SimpleSieve.class);
29-
3023
private SieveCallback clientCallback;
3124

3225
public SimpleSieve(SieveCallback clientCallback) {
@@ -62,21 +55,4 @@ public void sieve(long limit0) {
6255
}
6356
}
6457
}
65-
66-
/**
67-
* Test performance without load caused by processPrime().
68-
* @param args ignored
69-
*/
70-
public static void main(String[] args) {
71-
ConfigUtil.initProject();
72-
CountingCallback callback = new CountingCallback();
73-
long limit = 1000000;
74-
while (limit < Integer.MAX_VALUE) {
75-
long start = System.nanoTime();
76-
SimpleSieve sieve = new SimpleSieve(callback);
77-
sieve.sieve(limit);
78-
LOG.info("Sieving x <= " + limit + " found " + callback.getCount() + " primes in " + ((System.nanoTime()-start) / 1000000) + " ms");
79-
limit *=10;
80-
}
81-
}
8258
}

src/main/java/de/tilman_neumann/jml/primes/exact/SieveTest.java src/test/java/de/tilman_neumann/jml/primes/exact/AutoExpandingPrimesArrayPerformanceTest.java

+6-39
Original file line numberDiff line numberDiff line change
@@ -17,49 +17,17 @@
1717
import org.apache.logging.log4j.LogManager;
1818

1919
import de.tilman_neumann.jml.primes.bounds.NthPrimeUpperBounds;
20-
import de.tilman_neumann.util.Ensure;
2120
import de.tilman_neumann.util.ConfigUtil;
2221

2322
/**
24-
* Test performance and correctness of results of prime sieves.
23+
* Compares the performance of AutoExpandingPrimesArray and SegmentedSieve.
24+
*
25+
* Result: Not much of a difference.
26+
*
2527
* @author Tilman Neumann
2628
*/
27-
public class SieveTest {
28-
private static final Logger LOG = LogManager.getLogger(SieveTest.class);
29-
30-
private static void testCorrectness(int maxCount) {
31-
for (int count=100; count<=maxCount; count*=10) {
32-
LOG.info("Test correctness of first " + count + " primes...");
33-
34-
// get correct data
35-
CollectingCallback correctCallback = new CollectingCallback(count);
36-
SimpleSieve correctSieve = new SimpleSieve(correctCallback);
37-
int nthPrimeUpperBound = (int) NthPrimeUpperBounds.combinedUpperBound(count);
38-
correctSieve.sieve(nthPrimeUpperBound);
39-
int correctCount = correctCallback.count;
40-
int[] correctResult = correctCallback.array;
41-
Ensure.ensureEquals(count, correctCount);
42-
Ensure.ensureEquals(2, correctResult[0]);
43-
Ensure.ensureEquals(3, correctResult[1]);
44-
Ensure.ensureEquals(5, correctResult[2]);
45-
46-
// test segmented sieve
47-
CollectingCallback segmentedCallback = new CollectingCallback(count);
48-
SegmentedSieve segmentedSieve = new SegmentedSieve(segmentedCallback);
49-
segmentedSieve.sieve(nthPrimeUpperBound);
50-
int[] segmentedResult = segmentedCallback.array;
51-
Ensure.ensureEquals(count, segmentedCallback.count);
52-
for (int i=0; i<count; i++) {
53-
Ensure.ensureEquals(correctResult[i], segmentedResult[i]);
54-
}
55-
56-
// test sieve facade
57-
AutoExpandingPrimesArray primesArray = AutoExpandingPrimesArray.get().ensurePrimeCount(count);
58-
for (int i=0; i<count; i++) {
59-
Ensure.ensureEquals(correctResult[i], primesArray.getPrime(i));
60-
}
61-
}
62-
}
29+
public class AutoExpandingPrimesArrayPerformanceTest {
30+
private static final Logger LOG = LogManager.getLogger(AutoExpandingPrimesArrayPerformanceTest.class);
6331

6432
private static void testPerformance() {
6533
for (long count=100; ; count*=10) {
@@ -104,7 +72,6 @@ private static void testPerformance() {
10472
*/
10573
public static void main(String[] args) {
10674
ConfigUtil.initProject();
107-
testCorrectness(10000000); // 100m is quite slow but feasible; but array-storing algorithms will fail soon above that
10875
testPerformance();
10976
}
11077
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* java-math-library is a Java library focused on number theory, but not necessarily limited to it. It is based on the PSIQS 4.0 factoring project.
3+
* Copyright (C) 2018-2024 Tilman Neumann - [email protected]
4+
*
5+
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License
6+
* as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
7+
*
8+
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
9+
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
10+
*
11+
* You should have received a copy of the GNU General Public License along with this program;
12+
* if not, see <http://www.gnu.org/licenses/>.
13+
*/
14+
package de.tilman_neumann.jml.primes.exact;
15+
16+
import org.apache.logging.log4j.Logger;
17+
import org.apache.logging.log4j.LogManager;
18+
19+
import de.tilman_neumann.util.ConfigUtil;
20+
21+
/**
22+
* Performance test for the segmented sieve of Eratosthenes based on Kim Walisch's implementation at http://primesieve.org/segmented_sieve.html
23+
*
24+
* @author Tilman Neumann
25+
*/
26+
public class SegmentedSievePerformanceTest {
27+
private static final Logger LOG = LogManager.getLogger(SegmentedSievePerformanceTest.class);
28+
29+
/**
30+
* Test performance without load caused by processPrime().
31+
* @param args ignored
32+
*/
33+
public static void main(String[] args) {
34+
ConfigUtil.initProject();
35+
long limit = 1000000;
36+
while (true) {
37+
long start = System.nanoTime();
38+
CountingCallback callback = new CountingCallback(); // initialize count=0 for each limit
39+
SegmentedSieve sieve = new SegmentedSieve(callback);
40+
sieve.sieve(limit);
41+
LOG.info("Sieving x <= " + limit + " found " + callback.getCount() + " primes in " + ((System.nanoTime()-start) / 1000000) + " ms");
42+
limit *= 10;
43+
}
44+
}
45+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* java-math-library is a Java library focused on number theory, but not necessarily limited to it. It is based on the PSIQS 4.0 factoring project.
3+
* Copyright (C) 2019-2024 Tilman Neumann - [email protected]
4+
*
5+
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License
6+
* as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
7+
*
8+
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
9+
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
10+
*
11+
* You should have received a copy of the GNU General Public License along with this program;
12+
* if not, see <http://www.gnu.org/licenses/>.
13+
*/
14+
package de.tilman_neumann.jml.primes.exact;
15+
16+
import org.junit.BeforeClass;
17+
import org.junit.Test;
18+
19+
import static org.junit.Assert.assertEquals;
20+
21+
import de.tilman_neumann.jml.primes.bounds.NthPrimeUpperBounds;
22+
import de.tilman_neumann.util.ConfigUtil;
23+
24+
/**
25+
* Test performance and correctness of results of prime sieves.
26+
* @author Tilman Neumann
27+
*/
28+
public class SieveTest {
29+
private static final int NCOUNT = 10000000; // 100m is feasible, but array-storing algorithms will fail soon above that
30+
31+
private static long nthPrimeUpperBound;
32+
private static int correctCount;
33+
private static int[] correctResult;
34+
35+
@BeforeClass
36+
public static void setup() {
37+
ConfigUtil.initProject();
38+
// get correct data
39+
CollectingCallback correctCallback = new CollectingCallback(NCOUNT);
40+
SimpleSieve correctSieve = new SimpleSieve(correctCallback);
41+
nthPrimeUpperBound = NthPrimeUpperBounds.combinedUpperBound(NCOUNT);
42+
correctSieve.sieve(nthPrimeUpperBound);
43+
correctCount = correctCallback.count;
44+
correctResult = correctCallback.array;
45+
assertEquals(NCOUNT, correctCount);
46+
assertEquals(2, correctResult[0]);
47+
assertEquals(3, correctResult[1]);
48+
assertEquals(5, correctResult[2]);
49+
}
50+
51+
@Test
52+
public void testSegmentedSieve() {
53+
CollectingCallback segmentedCallback = new CollectingCallback(NCOUNT);
54+
SegmentedSieve segmentedSieve = new SegmentedSieve(segmentedCallback);
55+
segmentedSieve.sieve(nthPrimeUpperBound);
56+
int[] segmentedResult = segmentedCallback.array;
57+
assertEquals(NCOUNT, segmentedCallback.count);
58+
for (int i=0; i<NCOUNT; i++) {
59+
assertEquals(correctResult[i], segmentedResult[i]);
60+
}
61+
}
62+
63+
@Test
64+
public void testAutoExpandingPrimesArray() {
65+
AutoExpandingPrimesArray primesArray = AutoExpandingPrimesArray.get().ensurePrimeCount(NCOUNT);
66+
for (int i=0; i<NCOUNT; i++) {
67+
assertEquals(correctResult[i], primesArray.getPrime(i));
68+
}
69+
}
70+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* java-math-library is a Java library focused on number theory, but not necessarily limited to it. It is based on the PSIQS 4.0 factoring project.
3+
* Copyright (C) 2018-2024 Tilman Neumann - [email protected]
4+
*
5+
* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License
6+
* as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
7+
*
8+
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
9+
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
10+
*
11+
* You should have received a copy of the GNU General Public License along with this program;
12+
* if not, see <http://www.gnu.org/licenses/>.
13+
*/
14+
package de.tilman_neumann.jml.primes.exact;
15+
16+
import org.apache.logging.log4j.Logger;
17+
import org.apache.logging.log4j.LogManager;
18+
19+
import de.tilman_neumann.util.ConfigUtil;
20+
21+
/**
22+
* Performance test for the simple sieve of Eratosthenes.
23+
*
24+
* @author Tilman Neumann
25+
*/
26+
public class SimpleSievePerformanceTest {
27+
private static final Logger LOG = LogManager.getLogger(SimpleSievePerformanceTest.class);
28+
29+
/**
30+
* Test performance without load caused by processPrime().
31+
* @param args ignored
32+
*/
33+
public static void main(String[] args) {
34+
ConfigUtil.initProject();
35+
long limit = 1000000;
36+
while (limit < Integer.MAX_VALUE) {
37+
long start = System.nanoTime();
38+
CountingCallback callback = new CountingCallback(); // initialize count=0 for each limit
39+
SimpleSieve sieve = new SimpleSieve(callback);
40+
sieve.sieve(limit);
41+
LOG.info("Sieving x <= " + limit + " found " + callback.getCount() + " primes in " + ((System.nanoTime()-start) / 1000000) + " ms");
42+
limit *= 10;
43+
}
44+
}
45+
}

0 commit comments

Comments
 (0)