Der er lidt med noget managed versus non-managed som jeg ganske rigtigt skriver lidt om i ovenstående tråd. Men det vil jeg mere kalde et spørgsmål og program karakteristika end om program performance.
Det er vigtigt at forstå at .NET ikke er fortolket i normal betydning. Det bliver bare først compilet til ægte native første gang det bliver kørt.
Men derudover så har jeg et lille stykke kode jeg bruger til at teste rå tal-knusning med.
Resultater:
GCC 3.1 = 8 seconds MS VS6 standard = 6 seconds MS VS6 /Ox /G5 = 4 seconds MS .NET 1.1 SDK C = 5 seconds
Så ja MS er en lille smule bedre end GCC. Men ikke sådan helt vildt.
Så vidt jeg ved er den hurtigste compiler til x86 Intel's.
>> Arne_v Der er nok ikke meget garbage at collecte i forbindelse med "rå talknusning", og det er velsagtens med GC at hastighedsforskellene gør sig rigtigt bemærket? Medmindre du bruger objekter i stedet for simple typer! :)
Der er ganske rigtigt ikke noget at GC'e i.f.m. den tal-knusning.
Men der er ikke specielt stort overhead på GC. Så det bør ikke give anledning til de helt store hastigheds forskelle. Den store forskel ved GC i forhold til manuel kald af destructor er at det sker i klumper ikke kontinuerligt.
>> arne_v Alt andet lige, så koster det altså en del mere at tjekke hele hoben periodisk for referencer og cirkulære referencer, end de enkelte manuelle kald koster. Men bortset fra det synes jeg at GC er helt ok og ikke noget at kimse af! *S*
det er et fåtal af applikationer hvor det er nødvendigt at vælge sprog/platform udfra et hastighedskriterie - som regel er der andre designmæssige overvejelser der vejer noget tungere. Benchmarks såsom "talknusning" er ofte meget misvisende og bør tages med et gran salt. I rå talknusning er Java noget hurtigere end C, men det er jo sjældent tilfældet i reelle applikationer.
nu ved jeg jo ikke hvordan dit program ser ud, men i applikationer hvor man i mange iterationer udfører en simpel beregning har java en fordel i at være fortolket fordi jvm'en kan lave meget aggresive runtime optimeringer som selvsagt ikke kan lade sig gøre i sprog der kompileres til maskinkode. Jeg kan henvise til http://javabog.dk/VPJ/bog10.html hvor forfatteren viser dette. Han bruger det dog som argument for at java ikke er langsommere end C++ hvilket efter min mening er meget forkert i praksis, ganske som du siger.
1) Argumentationen bygger på dette postulat "JIT'en kan derimod observere kørslen nogle gange og konstatere, at while-betingelsen oftest er opfyldt, mens if-sætningen meget sjældent er det, og generere maskinkode, der er optimeret derefter." som der ikke føres noget bevis for og som mig bekendt er forkert for de fleste JVM'er.
2) Påstanden om at det er fra Java 1.2 at skiftet sker passer ikke med andres målinger. For SUN JVM er det først fra 1.4.
3) Eksemplet er helt hen i vejret fordi det er ikke et rent tal-knuse program men også et console IO program.
4) Hans påstand "Der bruges ingen objekter." er forkert da han laver et objekt per gennemløb (tal + " er et primtal.\n").
(iøvrigt så mener jeg at SUN JVM fra 1.4 er lige så hurtigt som native kode i den forstand at performance ikke længere kan begrunde et fravalg et Java).
Jeg er helt enig i at hans beskrivelse er noget fejlbehæftet. Det viser sig da også når jeg kører programmet at C++ udgaven er en anelse hurtigere (12.7s mod 13.4 til java - gcc 2.95 og java1.4.2-beta). Dette skyldes formentligt at det tager noget tid for jvm'en at initialisere - man kan eventuelt prøve at indlægge tidsmålingen i selve programmet.
Jeg er dog overbevist om at den ringe hastighedsforskel er et direkte resultat af fortolkningen som i hvert fald sun's jvm gerne skulle udføre som forfatteren beskriver. Det har efter min opfattelse intet med console IO at gøre - jeg nægter at tro på at java outperformer C++ på det punkt.
Jeg regner med at geninstallere timesys linux/real-time java når jeg får tid, det kunne i den forbindelse være interessant at lave nogle målinger. Men hastighedsmålinger er ofte noget bras, og som vi er enige om skal det sjældent lægges til grund for valg af sprog.
Det er dog interessant at se dine målinger af forskellige jvm's og jeg er imponeret over 1.4's performance.
arne_v skriver: 1) Argumentationen bygger på dette postulat "JIT'en kan derimod observere kørslen nogle gange og konstatere, at while-betingelsen oftest er opfyldt, mens if-sætningen meget sjældent er det, og generere maskinkode, der er optimeret derefter." som der ikke føres noget bevis for og som mig bekendt er forkert for de fleste JVM'er.
Det vil jeg gerne uddybe lidt, en while/if er jo bare nogle jumps i maskinkode, efter et stykke tid vil CPU'en have fundet ud af at disse enten tages ofte eller ikke tages (Branch prediction) det er moderne CPU ganske gode til, kun kode der skiftes meget imellem ikke taget/taget vil få CPU til at gå i selvsving og ydelsen til at falde enormt (forudsat at resten af system køre perfekt). Nye CPU kan ofter huske de sidste 4096 betingede hop og hvad der oftest bliv valgt.
Hvis en JiT først skal bruge tid på at analysere de hidtidige data og hop kan den komme meget langt efter en compilet løsning, især hvis de første data viser sig ikke at holde stik for resten.
ps. Processorne er ofte meget langt forud i deres beregninger i forhold til de betingelser der skal checkes og alle beregninger der er efter en fejl predicted hop skal kasseres, jeg mener at kunne huske at de nyeste Pentiummer er op til 85 nstruktioner forud og de nyeste powerPC'er er over 200 forud, i begges(???) tilfælde ca. den tid det i værste fald tager at hente data fra ram.
Ja det er lidt suspekt skrevet af ham forfatteren, jit'en evaluerer jo ikke while løkken hver gang som det måske kan tolkes af teksten..
Crash Course i sun's hotspot jvm: Al kode _køres fortolket_ en del gange alt imens koden profileres. Efter noget tid oversættes "hot spots" i koden til native, med aggresive optimeringer. På det tidspunkt har kompileren et bedre udgangspunkt for at optimere end en statisk kompiler har, derfor bliver det hurtigere. Når det normalt er svært at lave optimering af javakode efter de klassiske optimeringsprincipper såsom inlining skyldes det at der i java ofte er flere (virtuelle) metodekald og javas dynamiske egenskaber generelt. I kodeeksemplet fra javabogen er det ikke tilfældet. Jeg er enig i at den egentlige branch prediction naturligvis foretages af cpu'en, men faktum er at kode der kompileres til native er hurtigere end statisk kompilering. Hvordan skal man ellers forklare hvorfor java efterhånden er næsten ligeså hurtigt som andre sprog når java/fortolket kode generelt har en uendelig lang liste af faktorer der burde gøre det langsommere (igen virtuelle metoder, sikkerhedscheck, dynamisk loading der ødelægger tidligere optimeringer som derfor skal de-optimeres osv..) Men forfatteren skulle nok have gennemtænkt det kapitel lidt bedre.
Umiddelbart virker det som det loop kører med præcis samme hastighed uanset hvilket sprog og hvilken compiler man bruger !
Og det hænger formentlig sammen med at den kode skal lave X hel tals divisioner og de tager stort set hele CPU tiden og derfor er der ikke rigtigt nogle optimerings-muligheder.
Jeg har iøvrigt fået en anden forklaring på VM optimering som virker troværdig men som nok også har begrænset effekt. Og det er at en VM kan optimere på runtime efter præcis hvilken CPU der er i maskinen (og også efter hvor meget memory). Mens en compiler oversætter normalt til "hvad som helst der er Pentium kompatibelt" eller noget i den retning.
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.