Moi.
Ihan mielenkiinnosta olen koodannut softan, joka populoi arrayn satunnaisilla luvuilla 0 - 999 väliltä, jonka koko on 1007483647.
Tämän jälkeen lasketaan montako kakkosta on arrayssa.
lopuksi katsotaan aika kauanko kone ruksutti tässä tehtävässä.
Tämän olen koodannut sekä c että c#.
C# kielellä mono ruksuttaa tuota 20sek, mutta samoin tein c kielinen sanoo että out of memory. Mitä teen väärin?
Kone on 64bit ja kai tuo gcc on myös 64bit:
Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/7/lto-wrapper OFFLOAD_TARGET_NAMES=nvptx-none OFFLOAD_TARGET_DEFAULT=1 Target: x86_64-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Ubuntu 7.5.0-3ubuntu1~18.04' --with-bugurl=file:///usr/share/doc/gcc-7/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++ --prefix=/usr --with-gcc-major-version-only --program-suffix=-7 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-bootstrap --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu Thread model: posix gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)
#include <stdio.h> #include <stdlib.h> #include <time.h> #define ARRAY_SIZE 1007483647 #define MIN_RAND 0 #define MAX_RAND 999 int main(void) { clock_t begin = clock(); int array[ARRAY_SIZE]; int a; srand(time(NULL)); for (int i = 0; i < ARRAY_SIZE; i++) { a=rand()%(MAX_RAND - MIN_RAND+1)+MIN_RAND; array[i]=a; } printf("\n"); printf("kakkosia:\t "); int laske=0; for (int j = 0; j < ARRAY_SIZE; j++) { if (array[j]==2) laske++; } printf("%d,", laske); clock_t end = clock(); double time_spent = (double)(end - begin) / CLOCKS_PER_SEC; printf("\n"); printf("%f", time_spent); return 0; }
juffe kirjoitti:
C# kielellä mono ruksuttaa tuota 20sek, mutta samoin tein c kielinen sanoo että out of memory. Mitä teen väärin?
Kannattaa kysymykseen laittaa myös tuo saamasi virheilmoitus. On muuten julmetun kokoinen taulukko ja hyvä arvaus on, että oletuksena oleva pinon koko ei tuohon riitä ja tuosta tulee saamasi virheilmoitus. Kokeilepa huviksesi varata muistia taulukkoa varten vaikka malloc() funktiolla.
Kuten jalski epäili, varmasti et pysty pinosta varaamaan noin isoa taulukkoa oletusasetuksilla. Linuxin komentorivillä (ainakin Bashissa) on mahdollista säätää pinon maksimikokoa ennen ohjelman käynnistystä:
ulimit -s 5000000 # sallitaan noin viiden gigan pino
Koodin puolesta ratkaisuna voit tehdä taulukosta globaalin (funktion ulkopuolelle) tai staattisen (static-sanalla), tai voit varata taulukon ajon aikana malloc-funktiolla (jolloin pitää muistaa vastaava free, ellei halua pitää taulukkoa ohjelman loppuun asti).
Lopuksi voi vielä miettiä, onko järkeä arpoa luvut taulukkoon ja vasta sitten laskea kakkoset, kun suoraan voisi ensimmäisessä silmukassa laskea niitä kakkosia (tai halutessaan kaikkia lukuja 0–999) ja säästää neljä gigaa muistia.
Kiitos tuolla mallocilla rupesi toimimaan, mutta hieman noi pointterit epäselviä.....
Joo tosiaan, eihän tässä mitään järkeä olekaan. Halusin testata jonkinnäköistä suorituskykyä C ja C# välillä linux koneessa.
Jos jollain windows ja haluaa testata, niin alla koodit.
Mun lukemat oli C kielellä 14.75sek ja C# 21.5sek.
#include <stdio.h> #include <stdlib.h> #include <time.h> #define ARRAY_SIZE 1007483647 #define MIN_RAND 0 #define MAX_RAND 999 int main(void) { clock_t begin = clock(); //int array[ARRAY_SIZE]; int *array = (int*)malloc(ARRAY_SIZE * sizeof(int)); int a; srand(time(NULL)); for (int i = 0; i < ARRAY_SIZE; i++) { a=rand()%(MAX_RAND - MIN_RAND+1)+MIN_RAND; array[i]=a; } printf("\n"); printf("kakkosia:\t "); int laske=0; for (int j = 0; j < ARRAY_SIZE; j++) { if (array[j]==2) laske++; } printf("%d,", laske); clock_t end = clock(); double time_spent = (double)(end - begin) / CLOCKS_PER_SEC; printf("\n"); printf("%f", time_spent); return 0; }
using System; using System.Diagnostics; namespace ArrayReader { internal static class Program { private const int SampleCount = 1007483647; public static void Main(string[] args) { Stopwatch sw = new Stopwatch(); Random rnd = new Random(); int[] samples = new int[SampleCount]; sw.Start(); for (int i = 0; i < SampleCount; i++) { samples[i] = rnd.Next(0, 999); } int count = 0; for (int i = 0; i < SampleCount; i++) { if (samples[i] == 2) count++; } sw.Stop(); Console.WriteLine(count); Console.WriteLine((float)sw.ElapsedMilliseconds/1000); Console.ReadKey(); } } }
Aihe on jo aika vanha, joten et voi enää vastata siihen.