Calculating primes until a user-given value I am new to C# programming. I wrote a little program in C# to calculate all primes until a user-given value. Ignoring the lack of computing power I wrote this program to handle theoretically very huge numbers.

The code works properly. I have no error handling simply because it is a little program for myself. But I'd like some suggestions about error handling. :)

Can you give me suggestions to improve the code? Maybe even to make it faster?

using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;

namespace ConsolePrimes
{
    public static class Program
    {
        public static void Main(string[] args)
        {
            Console.WriteLine("Up to which number shall all primes be calculated?");
            string inputvar = Console.ReadLine();
            ulong inputnumber = Convert.ToUInt64(inputvar);
            var primes = new List&lt;ulong&gt;();
            primes.Add(2);
            primes.Add(3);
            bool isprime = false;
            double result = 0;
            for (ulong i = 4; i&lt;inputnumber; i++)
            {
                isprime = true;
                foreach (ulong prime in primes)
                {
                    result = i % prime;
                    if (result == 0)
                    {
                        isprime = false;
                        break;
                    }
                }
                if (isprime == true)
                {
                    primes.Add(i);
                }
            }
            int numberofprimes = primes.Count;
            Console.WriteLine("The Range from 0 to " + inputvar + " has " + Convert.ToString(numberofprimes) + " primes.");
            Console.WriteLine("The list of all primes is now getting exported to \"primes.txt\".");
            TextWriter tw = new StreamWriter("primes.txt");
            foreach (ulong nr in primes)
            {
               tw.WriteLine(nr);
            }
            tw.Close();
            Console.ReadLine();
        }
    }
}
So this is a curious writeup, because primes can be calculated in many, many ways.

That said, there's one huge optimization we can use to cut your search pattern in half, and it starts here:


for (ulong i = 4; i&lt;inputnumber; i++)
{



Fun fact: the only prime even number is 2, so we can actually rewrite this very quickly to remove half of the numbers you need to search:

for (ulong i = 5; i&lt;inputnumber; i += 2)
{


Bam. Cut our search grid in half.

The next thing I would do is remove 2 from the List&lt;ulong&gt; of results, and we'll insert it later, because that will never match any of the values we're searching now:

var primes = new List&lt;ulong&gt;();
primes.Add(3);
...
primes.Insert(0, 2);


That way we get another speed boost, without sacrificing any of the rest of our code. (Are there better ways to do this? Sure.)



Next, we need to talk about some "best practices" and such:

Console.WriteLine("The Range from 0 to " + inputvar + " has " + Convert.ToString(numberofprimes) + " primes.");


This is something we call "string concatenation", basically, string1 + string2. It's frowned upon, and we recommend not doing it. Instead, use a formatted string, in one of two ways:

Console.WriteLine("The Range from 0 to {0} has {1} primes.", inputvar, numberofprimes);
Console.WriteLine($"The Range from 0 to {inputvar} has {numberofprimes} primes.");


Either will work, though the second is only supported in C# 6.0.



Next, there's one more huge optimization to make, and it's at this line:

double result = 0;


You don't realize it, but there's a boatload of casting/conversions here that shouldn't exist. Replace double with ulong and it goes away.

What's happening, is i % prime is a ulong, that is being casted to a double when assigned to result. This is an expensive operation, because the two types are stored in memory in completely different formats. Change the type, and you should get a 50%+ speed boost. (At least, I did.)



Additionally, you don't really need result, you don't use it for anything. So, I recommend removing it, and rewriting the foreach as follows:

for (ulong i = 5; i &lt; inputnumber; i += 2)
{
    isprime = true;
    foreach (ulong prime in primes)
    {
        if (i % prime == 0UL)
        {
            isprime = false;
            break;
        }
    }
    if (isprime == true)
    {
        primes.Add(i);
    }
}


This gives you another speed boost, surprisingly.



Lastly, I recommend initializing the List with a default buffer. This should help avoid "resizing" that happens throughout the lifetime of the program. I used 500000, but as long as you use something reasonable (even 10000 is fine) it will give you a decent performance boost. (1-2%)



Overall, when we're done, the algorithm should look something like:

var primes = new List&lt;ulong&gt;(10000);
primes.Add(3);
bool isprime = false;
for (ulong i = 5; i &lt; inputnumber; i += 2)
{
    isprime = true;
    foreach (ulong prime in primes)
    {
        if (i % prime == 0UL)
        {
            isprime = false;
            break;
        }
    }
    if (isprime == true)
    {
        primes.Add(i);
    }
}
primes.Insert(0, 2);
int numberofprimes = primes.Count;