Код медленнее if(!((squareRoot&1)==0))
, чем без теста, потому что он редко дает преимущество.
Имейте в виду, что для большинства number
предел итерации никогда не достигается из-за раннего возврата из теста number%j
. Простые числа, как правило, становятся редкими по мере роста number
.
Редкая дополнительная итерация не компенсируется повторяющейся стоимостью теста.
Сравнение !((squareRoot&1)==0)
с number%2 ==0
является спор .
Метод тестирования быстродействия OP подвержен ошибкам, когда различия невелики: «в большинстве случаев он работает чуть медленнее», что свидетельствует о несоответствии.
A огромное количество времени в printf()
. Чтобы сравнить производительность вычислений, необходимо исключить операции ввода-вывода.
kill
тоже не такой точный.
Вместо этого сформируйте цикл, который останавливается, когда i
достигает значения, например, 4 000 000 000 и в этот раз.
У кода есть и другие недостатки:
unsigned long squareRoot = floor(sqrt(number));
может создать неправильный корень для большого number
из-за округления при преобразовании number
в double
и неточности подпрограммы sqrt()
. Ссылка OP обращается к математическому алгоритму , необходимому. Тем не менее, эта реализация кода C может легко потерпеть неудачу, учитывая ограничения реальных вычислений.
Вместо этого предложите
// Prime test for all unsigned long number
bool isPrime(unsigned long number) {
if (number % 2 == 0) { // This can be eliminated if `number` is always odd.
return number == 2;
}
for (unsigned long j = 3; j <= number/j; j += 2) {
if (number%j == 0) {
return false;
}
}
return number > 2;
}
Стоимость number/j
часто равна нулю в современных компиляторах, поскольку они видят number%j
и эффективно вычисляют как частное, так и остаток одновременно. Таким образом, предел j <= squareRoot
достигается 1) без дорогостоящего sqrt()
расчета 2) является точным для большого number
, в отличие от sqrt()
использования.
Использовать совпадающие спецификаторы. u
, а не d
для неподписанных типов.
// printf("Number %ld is a prime!\n", i);
printf("Number %lu is a prime!\n", i);
Использование глобального i
здесь является слабым стилем кодирования. Предложите перекодировать и передать вместо функции.
Для более существенных улучшений, посмотрите Сито Эратосфена и ведите список ранее найденных простых чисел и проверьте их, а не все нечетные числа.
Первичное тестирование - глубокий предмет с множеством более продвинутых идей.