2016-06-14 36 views
5

tôi đã viết đoạn mã sau để có được tất cả các số nguyên tố từ 2..Ntính số (suối và lambdas) Thủ

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) 
    ); 
} 

tôi tối ưu hóa nó bằng cách kiểm tra trong khoảng 2..sqrt (n) và lọc ra các số chẵn, nhưng bây giờ tôi muốn tối ưu hóa nó hơn bằng cách lưu trữ tất cả các số nguyên tố đã tìm thấy trước đây (tôi không quan tâm đến bộ nhớ), để tôi có thể lọc ra các số chia hết cho các số nguyên tố đó, chứ không phải bởi 2. Tôi biết có những giải pháp tốt hơn, nhưng nó chỉ là một bài tập về lambdas và suối.

+0

Tôi tin rằng việc tối ưu hóa tốt hơn là (a) thay đổi từ noneMatch() để anyMatch() và phủ nhận kết quả (b) Các hoạt động lọc bạn có thực sự là rất hạn chế để kiểm tra nếu số trong phạm vi giữa 2..sqrt (đầu vào) chia hết cho 2 và không kiểm tra các số nguyên tố khác như 3,5 .... Thay vì tất cả các bước này làm cho luồng trở lại ngay sau khi số có thể chia hết cho các 2,3,4,5, .... – Baski

+2

@Baski: tại sao bạn nghĩ rằng thay đổi từ 'noneMatch()' thành 'anyMatch()' và phủ nhận kết quả nào tối ưu hóa bất cứ điều gì? – Holger

+2

Nếu bạn muốn tối ưu hóa tốc độ với chi phí bộ nhớ, hãy thực hiện sàng của Eratosthenes bằng cách sử dụng 'BitSet'. Nhưng, vì đây là một bài tập trong các luồng, bạn có thể sử dụng 'getPrimesStream' bên trong' isPrime' để có được các thừa số chính để kiểm tra: 'return number == 2 || getPrimesStream ((dài) ceil (sqrt (số))). noneMatch (số chia -> số% số chia == 0); ' – Misha

Trả lời

3

nhưng bây giờ tôi muốn tiếp tục tối ưu hóa nó bằng cách lưu trữ tất cả trước đây tìm thấy số nguyên tố

Kể từ đó sẽ yêu cầu lưu trữ những giá trị ở giữa các đường ống dẫn dòng, tức là một hoạt động trung gian và hầu hết các dòng trung gian các hoạt động phải là không trạng thái theo tài liệu của chúng, bạn đang cố sử dụng công cụ sai cho công việc ở đây.

Có thể triển khai các tùy chọn trạng thái bằng cách trích xuất một dòng của Spliterator, gói nó thành một luồng tùy chỉnh và ghi lại nó vào một luồng mới, nhưng trong trường hợp này dường như không phù hợp.

Vì bạn đang cố gắng thực hiện nhiệm vụ tính toán trạng thái và song song, bạn có thể muốn xem xét fork-join framework hoặc CompletableFuture thay thế. Cái trước đây cũng được sử dụng như một phần của việc thực hiện luồng song song và sau này làm cho việc tính toán và kết quả của chúng trở nên dễ dàng hơn.

1

thử này

public static boolean isPrime(final long number) { 
    return LongStream.range(2,(long) Math.ceil(Math.sqrt(number + 1))).noneMatch(x -> number % x == 0); 
} 
+0

Tôi có thể biết tại sao số + 1 không? –

+0

@JigarNaik Tôi có thể sai. Tôi đã làm nó chỉ để tránh làm tròn lỗi. – dehasi

+0

Tại sao không gọi noMatch() thay vì anyMatch() và ký hiệu phủ định? –