Почему эта программа "с" медленная на win10, но быстрая на linux
Я написал небольшую тестовую программу в качестве небольшого теста для некоторых языков, которые я рассматривал. Это не говорит много о языке, но это дает мне немного опыта использования языка, а также дает небольшой тест производительности. Один и тот же алгоритм используется для всех языков. Я использовал это с C++, Rust, Go, Crystal, "V", Java, Dart, JS. На самом деле меня интересует только скомпилированный внутренний язык, но я включил некоторые другие из интереса. Эталон состоит в том, чтобы просто найти простые числа до определенного числа. Алгоритм, вероятно, не самый быстрый, но это один и тот же алгоритм для всех программ.
Чтобы вычислить простые числа до 10 миллионов на моем ПК i7 с почти всеми этими языками, требуется менее 13 секунд. Java занимает около 14 секунд.
Однако я также написал эту программу, используя "C", и это заняло около 675 секунд, и я не знаю почему. Я не программист на "Си", но у меня есть опыт работы с несколькими языками. Я хочу знать, что я сделал не так в программе. Мне крайне странно, что он работает так, как ожидалось в "C" на Linux, но не на Win10.
Я разместил код здесь:
https://controlc.com/3179b32a
/* CALCULATE PRIME NUMBERS */ /* THIS IS NOT DESIGNED TO BE SUPER-OPTIMAL, BUT AS A BENCHMARK. */ #include <stdio.h> #include <stdlib.h> #include "strings.h" #include <sysinfoapi.h> // long fnCalcSqrt(long); int main(void) { printf("\nCalculate number of prime integers from 2 to n million"); long iMillions = 0; char sMillions[10]; while (iMillions < 1 || iMillions > 100) { printf("\nEnter number of millions (1 to 100): "); fgets(sMillions, sizeof(sMillions), stdin); if (strlen(sMillions) < 2) { return 0; } iMillions = atoi(sMillions); if (iMillions < 1 || iMillions > 100) { printf("Must be from 1 to 100"); } } long iEndVal = iMillions * 1000000; long iCurrent, iDiv, iSqrt, tfPrime, iPrimeTot = 0; printf("Started: calculating primes from 2 to %ld,000,000 .......\n", iMillions); long iElapsedMs = GetTickCount(); for (iCurrent = 2; iCurrent <= iEndVal; iCurrent++) { if (iCurrent % 2 != 0 || iCurrent == 2) { iSqrt = fnCalcSqrt(iCurrent); tfPrime = 1; for (iDiv = 2; iDiv <= iSqrt; iDiv++) { if ((iCurrent % iDiv) == 0) { if (iDiv != iCurrent) { tfPrime = 0; } break; } } iPrimeTot += tfPrime; } } iElapsedMs = GetTickCount() -iElapsedMs; printf("Finished. prime total = %ld\n", iPrimeTot); printf("Elapsed = %ld.%ld seconds\n", iElapsedMs/1000, iElapsedMs % 1000); return 0; } long fnCalcSqrt(long iCurrent) /* CALC APPROXIMATE SQRT (NOT EXACT) */ { long iProd = 0, iPrevDiv = 0, iDiff = 0; long iDiv = iCurrent / 10; if (iDiv < 2) { iDiv = 2; } while (1) { iProd = iDiv * iDiv; if (iPrevDiv < iDiv) { iDiff = (iDiv - iPrevDiv) / 2; } else { iDiff = (iPrevDiv - iDiv) / 2; } iPrevDiv = iDiv; if (iProd < iCurrent) /* iDiv IS TOO LOW */ { if (iDiff < 1) { iDiff = 1; } iDiv += iDiff; } else { if (iDiff < 2) { return iDiv; } iDiv -= iDiff; } } }
Что я уже пробовал:
I presumed that I had made a mistake, and I presume that I have, but I couldn't find where. So, I set up WSL2 on my PC and compiled and ran the program on Ubuntu and it took 12.5 seconds to run. This is the exact same program that I ran on Win10 that took 675 seconds - about 50 times longer. So, I presumed it must have been the compiler on Windows, so I tried different compilers on Windows - MS, GCC, Tiny C, Pelles C. The result was the same with all - 675 seconds or more. It was then that I coded it in JS in order to transpile to "C", however that did not work (did not compile), and if I modified it to work I would have ended up with essentially my own "C" program. Thinking that it may be my PC, I tried on another Win10 PC, but essentially the same problem.
Shao Voon Wong
Не забудьте включить оптимизатор и построить в режиме выпуска в VC++. Режим отладки имеет все виды проверок, которые замедляют выполнение.