c# linq ile asal sayı bulma

asal sayılar yanlış hatırlamıyorsam şifreleme(crypto) algoritmalarında yada çok nadir abuk gubik işlerde kullanılıyorlar. velhasılı bir vakit ihtiyaç olabiliyor kendileri asal 🙂 linq ile c#da asal sayı bulma yolları

var asallar = Enumerable.Range(1, 20)
.Where(i => i != 1 && !Enumerable.Range(2, i - 2).Any(j => i % j == 0));

bu yöntemde adım adım gidiliyor ve sayıya kadar bölme kontrolü yapılıyor. ikinci yöntemimiz biraz daha mantıklı bu sefer sayının kareköküne kadar bölme kontrolü yapılıyor. bu arada bölme kontrolü mod ile yapılıyor.

var asallar = Enumerable.Range(1, 20)
.Where(x => x != 1 &&
!Enumerable.Range(2, (int)Math.Sqrt(x)).Any(y => x != y && x % y == 0));

son adımda parallel olarak bu algoritmayı çalıştırmak. yapmamız gereken “AsParallel” eklemek:

var asallar = Enumerable.Range(1, 20).AsParallel()
.Where(x => x != 1 &&
!Enumerable.Range(2, (int)Math.Sqrt(x)).Any(y => x != y && x % y == 0));

ilk iki algoritmanın performans testleri

Döngü boyu adım adım algo kareköklü algoritma
2000 .011 saniye .001 saniye
200,000 31 saniye .2 saniye
2,000,000 2,400 saniye (40 dakika) 4.5 saniye

burda döngü boyu gidilen rakamlar demek yani 0 dan 2000 e kadar olan sayılardaki harcanan zaman saniye olarak. son olarakda paralel yapıda çalış dediğimizdeki performans testleri buyrun:

2000 .029 saniye
200,000 .155 saniye
2,000,000 2.6 saniye
20,000,000 65 saniye

rakamlar büyünce gerçekten fark eden bir performans farkı var.