napisałem poniższy kod, żeby uzyskać wszystkie liczby pierwsze z 2..nobliczania liczb pierwszych (strumienie i lambda)
private static LongStream getPrimesStream(long number) {
return LongStream.range(2, number + 1)
.filter(PrimeStreamTest::isPrime);
}
private static boolean isPrime(final long number) {
return number == 2 || (number % 2 != 0 && LongStream
.range(2, (long) Math.ceil(Math.sqrt(number + 1)))
.filter(n -> n % 2 != 0)
.noneMatch(divisor -> number % divisor == 0)
);
}
ja go zoptymalizowany poprzez sprawdzenie w zakresie 2..sqrt (n) i filtrowanie liczb parzystych, ale teraz chcę ją jeszcze bardziej zoptymalizować, przechowując wszystkie poprzednio znalezione liczby pierwsze (nie dbam o pamięć), tak, że mogę odfiltrować liczby podzielne przez te liczby pierwsze, a nie tylko te, które są podzielne przez 2. Wiem, że są lepsze rozwiązania, ale to tylko ćwiczenie na lambdach i strumieniach.
Uważam, że lepiej optymalizacji jest do: (a) zmianę z noneMatch(), aby anyMatch() i neguje wynik (b) Działanie filtra masz naprawdę bardzo ogranicza się do sprawdzenia, czy liczba w zakresie od 2. sqrt (wejście) jest podzielna przez 2 i nie sprawdza innych liczb pierwszych, np. 3,5 .... Zamiast wszystkich tych kroków, strumień powraca, gdy tylko liczba jest podzielna przez 2,3,4,5, ... – Baski
@Baski: dlaczego myślisz, że przejście z 'noneMatch()' na 'anyMatch()' i zanegowanie wyniku zoptymalizuje cokolwiek? – Holger
Jeśli chcesz zoptymalizować prędkość za cenę pamięci, użyj sita Eratostenesa używając 'BitSet'. Ale ponieważ jest to ćwiczenie w strumieniach, możesz użyć 'getPrimesStream' wewnątrz' isPrime', aby sprawdzić czynniki pierwotne przed: 'return number == 2 || getPrimesStream ((long) ceil (sqrt (number))) noneMatch (dzielnik -> numer% dzielnik == 0); ' – Misha