[Java] VM optimalisaties en performance

Pagina: 1
Acties:
  • 378 views sinds 30-01-2008
  • Reageer

Verwijderd

Modbreak:Let op!

Deze topic is afgesplitst vanuit [rml][ Java] volatile keyword[/rml], en gaat over verschillende optimalisaties die de VM al dan niet kan doen at runtime, vergeleken met compile-time optimalisaties van native talen zoals C++
Alarmnummer schreef op maandag 01 augustus 2005 @ 08:47:
Maar de compiler die voert soms wat optimalisaties uit en daardoor worden er copies gemaakt van die variable.
Ik denk dat de java->bytecode compiler in Java dat niet (meer) doet, maar de JVM (eigenlijk ook een compiler, maar dan een dynamische ;) ).

[ Voor 29% gewijzigd door .oisyn op 04-08-2005 17:37 ]


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Verwijderd schreef op maandag 01 augustus 2005 @ 23:22:
[...]
Ik denk dat de java->bytecode compiler in Java dat niet (meer) doet
Uiteraard. Bytecode is de binaire verse van sourcecode waarbij erg weinig informatie verloren gaat en niet geoptimaliseerd wordt. De optimize compilerflag werkt daarom ook niet.
, maar de JVM (eigenlijk ook een compiler, maar dan een dynamische ;) ).
De JIT-Compiler.

Maar probeerde je me iets duidelijk te maken of had je gewoon ff zin om te reageren ;)

Verwijderd

.oisyn schreef op maandag 01 augustus 2005 @ 11:07:
Dus nee, de compiler kan dat hier niet optimaliseren. De VM wel natuurlijk aangezien hij alle benodige info heeft, maar ik betwijfel of dat ook zo gespecificeerd is.
Volgens mij kan de VM dat ook niet in Java. Je hebt namelijk iets dat reflection heet. Hiermee kun je methods en properties van een willekeurig object benaderen via een API. Je kunt deze dan runtime banaderen dmv een invoke method die een oa een String als argument heeft wat de property (field/data member) of method identificeerd.

Je kunt dus theoretisch nooit bepalen door analyse of een data member wel of niet benaderd gaat worden in Java.

Verwijderd

Alarmnummer schreef op maandag 01 augustus 2005 @ 23:29:
[...]
Maar probeerde je me iets duidelijk te maken of had je gewoon ff zin om te reageren ;)
Beiden :) Maar het was eigenlijk meer bedoeld om de situatie te verduidelijken voor de C++ mensen. Met 'de compiler' zullen veel mensen in eerste instantie aan javac en consorten denken (de java -> bytecode compiler dus). Wat meer advanced java mensen (jij dus vast ook wel ;) ) weten dat deze (statische) compiler eigenlijk weinig doet en dat je dus de JVM 'jit' compiler bedoelde.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 28-04 14:41

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Nou vind ik het idd interessant om te lezen dat de compiler (javac) idd geen enkele optimalisaties doet. Weet iemand waar ik meer kan lezen over wat voor optimalisaties de VM zelf allemaal doet? 't Zal wel per VM implementatie verschillen maar de standaard Java VM is fine :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

.oisyn schreef op dinsdag 02 augustus 2005 @ 12:00:
Nou vind ik het idd interessant om te lezen dat de compiler (javac) idd geen enkele optimalisaties doet. Weet iemand waar ik meer kan lezen over wat voor optimalisaties de VM zelf allemaal doet?
In principe is dat afhankelijk van de implementatie van de vm en van het os/cpu.

In principe is de JIT-compiler een onnodige stap (wel handig uiteraard zodat java niet zo traag is, want volledig interpreteren is te langzaam om serieus gebruikt te worden).

  • grhmpf
  • Registratie: December 2000
  • Laatst online: 29-05-2022

grhmpf

Android <3

.oisyn schreef op dinsdag 02 augustus 2005 @ 12:00:
Nou vind ik het idd interessant om te lezen dat de compiler (javac) idd geen enkele optimalisaties doet. Weet iemand waar ik meer kan lezen over wat voor optimalisaties de VM zelf allemaal doet? 't Zal wel per VM implementatie verschillen maar de standaard Java VM is fine :)
Hmm, javac misschien niet (hoewel ik dat ook niet zeker weet, volgens mij worden loops en dergelijke welzeker geoptimized), maar als je bijvoorbeeld kijkt naar de Eclipse compiler die optimized wel degelijk. In de zin van ongebruikte vars niet in bytecode opnemen bijvoorbeeld.

Even een testje gedaan en de Eclipse compiler knikkert in dit geval inderdaad k weg:
Java:
1
2
3
4
5
6
    public void test()
    {
        int j = 10;
        int k = 20;
        System.out.println(j);
    }


Met javap krijg je dan dit:
code:
1
2
3
4
5
6
7
8
9
public void test();
  Code:
   0:   bipush  10
   2:   istore_1
   3:   getstatic       #20; //Field java/lang/System.out:Ljava/io/PrintStream;
   6:   iload_1
   7:   invokevirtual   #26; //Method java/io/PrintStream.println:(I)V
   10:  return
}


Geen spoor van een bipush 20 dus...

Ik heb ook wat met loops getest, maar die blijven in de bytecode zitten dus die worden dan blijkbaar in de JIT stap geoptimized (of niet :))

[ Voor 35% gewijzigd door grhmpf op 02-08-2005 23:31 ]


Verwijderd

Alarmnummer schreef op dinsdag 02 augustus 2005 @ 12:38:
[...]

In principe is dat afhankelijk van de implementatie van de vm en van het os/cpu.

In principe is de JIT-compiler een onnodige stap (wel handig uiteraard zodat java niet zo traag is, want volledig interpreteren is te langzaam om serieus gebruikt te worden).
Idd. Heel af en toe dwingt men je om JIT uit te zetten wegens bugs in de VM. Dat is momenteel zo bij Eclipse en SUN JVM voor AMD64. Er blijkt daar een bug te zitten in de code die de JIT compiler produceerd, en deze wordt toevallig getriggerd door een method ergens in Eclipse. Echter, met JIT uit wordt het -zo- langzaam dat het gewoon niet werkbaar meer is.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 28-04 14:41

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Ik vind dit een van de minst interessante optimalisaties en had ik ook zeker wel verwacht. Het is nogal onzin om j en k hier als locale variabelen op te slaan, en dat samen met loop unrolling is zo'n beetje het enige wat de javac compiler kán doen.

Wat ik wel interessant vind is inlining. Method invocation en het accessen van class members van een andere class dan this was vroeger altijd rete-traag (en dan praat ik over medio 2001), daar had ik in mijn softwarerenderer behoorlijk last van. Daarnaast is de tendens in OO programming altijd al geweest dat je je members private maakt en daar get/set accessors voor maakt. Wat ik me dus afvraag is of deze kleine functies tegenwoordig direct geinlined worden als de aanroepende functie gecompileerd wordt naar machinecode in de JIT compiler. Dit soort kleine optimalisaties geven in Java imho al een behoorlijke performanceboost.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

.oisyn schreef op woensdag 03 augustus 2005 @ 11:17:
[...]
Ik vind dit een van de minst interessante optimalisaties en had ik ook zeker wel verwacht. Het is nogal onzin om j en k hier als locale variabelen op te slaan, en dat samen met loop unrolling is zo'n beetje het enige wat de javac compiler kán doen.
Loop unrollen is geloof ik ook geen taak van de 1e java compiler (dus de java->bytecode compiler). Dit is allemaal taak van de JIT.. de JIT kan namelijk vrij agressieve optimalisaties doen die helemaal voor het platform/cpu waarvoor de jit compileerd, is geoptimaliseerd. Het is de bedoeling van de bytecode zo direct mogelijk bij de java code te blijven. Bytecode kan je in dat opzicht ook goed vergelijken met c-code. Pas als de JIT/C-compiler is geweest is het helemaal op maat gemaakt, maar voordat die zijn geweest is het nog volledig platform onafhankelijk en totaal niet geoptimaliseerd.
Wat ik wel interessant vind is inlining. Method invocation en het accessen van class members van een andere class dan this was vroeger altijd rete-traag (en dan praat ik over medio 2001), daar had ik in mijn softwarerenderer behoorlijk last van. Daarnaast is de tendens in OO programming altijd al geweest dat je je members private maakt en daar get/set accessors voor maakt. Wat ik me dus afvraag is of deze kleine functies tegenwoordig direct geinlined worden als de aanroepende functie gecompileerd wordt naar machinecode in de JIT compiler. Dit soort kleine optimalisaties geven in Java imho al een behoorlijke performanceboost.
Dat wordt idd al gedaan. Voor simpele properties is de get/setter eigelijk een compiletime kwestie ivm illegaal aanspreken. (Je mag dus niet iets setten als er geen setter is)

Maar als de JIT is geweest wordt een a.getB() gewoon vertaald naar een a.b (mits het een eenvoudige getter/setter is.. als er extra logica bij zit dan wil dit uiteraard niet meer)

[ Voor 12% gewijzigd door Alarmnummer op 03-08-2005 11:56 ]


  • grhmpf
  • Registratie: December 2000
  • Laatst online: 29-05-2022

grhmpf

Android <3

.oisyn schreef op woensdag 03 augustus 2005 @ 11:17:
[...]


Ik vind dit een van de minst interessante optimalisaties en had ik ook zeker wel verwacht. Het is nogal onzin om j en k hier als locale variabelen op te slaan, en dat samen met loop unrolling is zo'n beetje het enige wat de javac compiler kán doen.
Ben ik helemaal met je eens, maar ik dacht dat de stelling was dat javac helemaal niets deed en dat is natuurlijk ook niet helemaal waar.
Wat ik wel interessant vind is inlining.
...
Zoals Alarmnummer al zegt is dat dus de taak van de JIT compiler en daar zitten zeker wat optimalisaties voor in hotspot.

http://www.artima.com/designtechniques/hotspot3.html is misschien wel aardig, hoewel ze totaal niet op details ingaan...

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 28-04 14:41

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Ik had het dan ook over de VM, goed blijven lezen he ;)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • grhmpf
  • Registratie: December 2000
  • Laatst online: 29-05-2022

grhmpf

Android <3

Ja hee ik heb vakantie hoor :)

  • misfire
  • Registratie: Maart 2001
  • Laatst online: 12-10-2024
Dit begint wel off-topic te raken maar ik kom op het einde wel met een keyword. ;)

Java compilers zullen over het algemeen inderdaad weinig optimalisaties doorvoeren in hun bytecode. Het enige wat je er aan kunt tweaken is het weg-optimaliseren van ongebruikte code, niet opnemen van debugging informatie en bijvoorbeeld extra constructies op te nemen om exception handling te versnellen (kan in Eclipse compiler). De java compiler moet code klasse voor klasse compileren en heeft daarom relatief weinig context om high level optimalisaties te kunnen doen.

Het echte interessante optimaliseerwerk gebeurt in de JIT compiler. Zaken als method inlining worden hier dynamisch bepaald op basis van bereikbaarheidspaden die tijdens runtime pas echt opgelost kunnen worden. Er is dan echter wel een schat aan informatie waarmee geoptimaliseerd kan worden, veel meer dan de (traditionele) compileer processen.

Java, .NET en ander JIT compiler constructies hebben hiermee de potentie om de vloer aan te vegen met programmeeromgevingen als C en C++. Verschillende micro-benchmarks laten dat nu al zien. Tel hierbij op de performancevoordelen die een garbage collector en real-time adaptive thread management je kunnen bieden op serieuze computersystemen, en je weet dat de dagen van unmanaged code voor het schrijven van applicaties geteld zijn.

Je kunt de JIT compiler (en de runtime) een handje helpen tijdens het schrijven van Java code. De regel is dat hoe strakker je Java code schrijft hoe beter de mogelijkheden zijn voor de omgeving om te gaan optimaliseren. Hou rekening met variabele scoping, maak klasses, methodes en velden final als het kan, maak inner klasses static als het kan en voorkom het gebruik van synthetic accessors.

Als je nu niet weet waar ik het over heb, niet getreurd! De allerbeste manier om snelle code te schrijven blijft ouderwets gezond verstand gebruiken en dingen op de meest simpele en efficiente manier oplossen. De beste compiler zit namelijk nog steeds achter het toetsenbord. :)

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 28-04 14:41

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
misfire schreef op woensdag 03 augustus 2005 @ 19:44:
Java, .NET en ander JIT compiler constructies hebben hiermee de potentie om de vloer aan te vegen met programmeeromgevingen als C en C++.
Ja en nee. Het hebben van runtime informatie kan enorm schelen, maar een taal als Java is te restrictive om het op te nemen tegen C++. Java heeft nog altijd geen pointers en geen value-type objects, constructies die performance drastisch beinvloeden. Daarnaast wordt er gewoon nog teveel gecontrolleerd (array access, typecasting, niet volledige x87 compatible floating point unit, etc.). Je hebt helemaal gelijk als je zegt dat een JIT compiler beter kan optimaliseren dan een traditionele C++ compiler, je hebt echter imho geen gelijk als Java als taal C++ zou kunnen outperformen.
Tel hierbij op de performancevoordelen die een garbage collector
Onzin, waarom zou een garbage collector performance voordelen hebben? Het is een extra analyse stap die gedaan moet worden, en niet gedaan hoeft te worden in C++, altijd meer overhead dus. En vergeet niet dat je in C++ vrijwel alle side-effects van het memory model van de Java VM kunt simuleren zonder alteveel moeite.
en real-time adaptive thread management
Ik zie niet in hoe Java meer invloed kan hebben op dingen die door je OS geregeld worden dan dat je in een native taal kunt bewerkstelligen.
Als je nu niet weet waar ik het over heb, niet getreurd! De allerbeste manier om snelle code te schrijven blijft ouderwets gezond verstand gebruiken en dingen op de meest simpele en efficiente manier oplossen. De beste compiler zit namelijk nog steeds achter het toetsenbord. :)
Nou hoop ik hier dat je het niet tegen mij hebt, en anders stel ik voor om even op m'n profile te klikken ;)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Macros
  • Registratie: Februari 2000
  • Laatst online: 27-04 11:06

Macros

I'm watching...

Het final keyword in methode declaraties heeft geen invloed op de performance van je applicatie. Ik weet niet hoe het zit met fields, maar dat zal waarschijnlijk weinig invloed hebben, behalve dat de JIT die waardes agressiever kan cachen. Wat vooral voordeel heeft in threaded omgevingen.
Java heeft nog altijd geen pointers en geen value-type objects, constructies die performance drastisch beinvloeden.
Alle objecten zijn een soort van pointers, het zijn in iedergeval referenties. Ik zie niet zo snel in waarom 'pointers' de performance van C groter kan laten zijn dan Java, als dat het enige verschil zou zijn...
Array access and type casting zijn juist die dingen die weggeoptimaliseerd worden door de hedendaagse JIT compilers.
Garbage collection is meestal sneller dan het 1 voor 1 aanvragen en vrijgeven van kleine stukjes geheugen wat vooral gebeurd in C/C++ applicaties. GC heeft ook als voordeel dat het het geheugen kan compacten, zodat het niet enorm gefragmenteerd raakt, wat ook een probleem kan zijn in lang lopende C/C++ applicaties die voortdurend geheugen alloceren en dealloceren.

"Beauty is the ultimate defence against complexity." David Gelernter


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Macros: Het final keyword in methode declaraties heeft geen invloed op de performance van je applicatie.
Waar baseer je dat op?

Ik betwijfel of het klopt: final methods kunnen niet overridden worden, waardoor ze beter geinlined kunnen worden. Dit geldt nog sterker voor final classes, waarbij geen enkele methode meer overridden kan worden.

Zie ook:
http://www.javaperformancetuning.com/tips/final.shtml

Uiteraard betekent dit niet dat je als een gek allerlei methoden als final moet gaan declareren. Als je zo de performance van je applicatie gaat proberen te verbeteren ben je natuurlijk fout bezig en kan je misschien beter een whole-program compiler gebruiken.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

mbravenboer schreef op woensdag 03 augustus 2005 @ 21:52:
[...]

Waar baseer je dat op?

Ik betwijfel of het klopt: final methods kunnen niet overridden worden, waardoor ze beter geinlined kunnen worden. Dit geldt nog sterker voor final classes, waarbij geen enkele methode meer overridden kan worden.
Er staat me ook zoiets bij dat de JIT slim genoeg was om dit te ontdekken zonder een final modifier.

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Alarmnummer: Er staat me ook zoiets bij dat de JIT slim genoeg was om dit te ontdekken zonder een final modifier.
Inderdaad, de inlining kan dan zelfs ongedaan worden als er later toch klassen bekend worden die de inlined methode overriden. Uiteraard is dat een dure operatie ... Als ik het goed heb, werd dit een keer uitgelegd in een JavaOne presentatie over Hotspot.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Maar als er geen verschil is tussen een final en niet final methode, dan heeft het 'final' zijn ook geen invloed op de performance. En is een argument voor de stelling van Macros.
Macros: Het final keyword in methode declaraties heeft geen invloed op de performance van je applicatie.

[ Voor 3% gewijzigd door Alarmnummer op 03-08-2005 22:39 ]


  • Macros
  • Registratie: Februari 2000
  • Laatst online: 27-04 11:06

Macros

I'm watching...

Ik doelde eigenlijk op final keywords bij methode argumenten declaraties. Sorry, was vergeten dat je ook methodes individueel als final kon declareren.
Waar ik die uitspraak op baseerde was de inspectie van de class file die werd gegenereerd. Final argumenten zijn exact hetzelfde als niet final argumenten in the bytecode.

"Beauty is the ultimate defence against complexity." David Gelernter


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Macros schreef op woensdag 03 augustus 2005 @ 22:42:
Ik doelde eigenlijk op final keywords bij methode argumenten declaraties.
Ik zie dit wel eens in code en ik heb echt zoiets van: laat dat! Heeft totaal geen toegevoegde waarde. Als iemand in een methode een argument wil aanpassen, dan kan hij dat doen. De scope van de problematiek is meestal maar een 10/15 regels, dus imho totaal achterlijk om daar met finals te gaan werken.

Verder betwijfel ik of een compiler niet kan achterhalen of een argument readonly is, dus ik zie niet in waarom een mens voor compiler moet spelen.

Verwijderd

.oisyn schreef op woensdag 03 augustus 2005 @ 20:38:
[...]
Java heeft nog altijd geen pointers en geen value-type objects
Oisyn, is dat geen tegenspraak? Je hebt toch -of- een name die een pointer is -of- een name die direct een object is.

Hoe dan ook, je bewering (zoals ik die hier lees) zou zowieso fout zijn. Java heeft juist -alleen maar- pointers. De enige niet-pointer dingen zijn primitives zoals een int of float. Bedoel je niet dat je in Java geen pointer berekeningen kan doen?

Het feit dat java geen value-type objects heeft is iets wat de taal een zekere in-effecientie kan geven. In diverse gevallen is het gebruik van stack-based allocatie (en deallocatie!) veel goedkoper dan alloceren op de heap. Ook voor het composite pattern kunnen value-type object data members veel efficienter zijn: je object wordt dan gealloceerd als 1 groot block in het geheugen. Bij de gedwongen pointer voor de data members in Java classen, staat je Java object dus altijd ge-scattered in je memory. Een zelfde soort verhaal geldt voor primitieve arrays.

Wel is het zo dat alleen de wat gevorderde programmeurs voordeel kunnen halen uit stack vs heap allocatie wat performance betreft. Java claimde altijd juist wat makkelijker te willen zijn en daarvoor best wat kracht en performance te willen inleveren.

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Verwijderd schreef op woensdag 03 augustus 2005 @ 22:56:
[...]
Het feit dat java geen value-type objects heeft is iets wat de taal een zekere in-effecientie kan geven.
Kijk eens naar Javalution

Verwijderd

Ziet er wel interesant uit, maar na een hele snelle blik erop is het me niet helemaal duidelijk of dit nu een library of een VM/compiler implementatie is? Het lijkt er meer op dat het een lib is, maar als je iets bekijkt als:
Objects can be allocated on the "stack" to avoid garbage collection.
Hoe kan dat dan zonder VM interventie? Tevens zal Java dan ook openstaan voor het nadeel van o.a. stack based allocation: ongeldige pointers met een address anders dan NULL. De hele Java VM kent dit principe normaal helemaal niet, dus ik vraag me af wat er hier dan gebeurt.

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

Verwijderd schreef op donderdag 04 augustus 2005 @ 00:05:
[...]


Ziet er wel interesant uit, maar na een hele snelle blik erop is het me niet helemaal duidelijk of dit nu een library of een VM/compiler implementatie is?
Het is een library.
Hoe kan dat dan zonder VM interventie?
Ik weet ook niet precies hoe het werkt. Heb er in het verleden wel eens iets mee gedaan, maar had geen echte performance verbeteringen ontdekt.
Tevens zal Java dan ook openstaan voor het nadeel van o.a. stack based allocation: ongeldige pointers met een address anders dan NULL. De hele Java VM kent dit principe normaal helemaal niet, dus ik vraag me af wat er hier dan gebeurt.
Je kunt wel een object uit de stack naar de heap trekken.

Het is al tijden geleden dat ik er naar gekeken heb, dus ik heb geen informatie over ins en outs. Persoonlijk heb ik niet zo`n hele hoge pet op van het project. Hij spamt vaak op Javalobby en geeft kritiek op sun implementaties. Maar op het moment dat echte testen worden uitgevoerd dan komen zijn resultaten niet overeen met de werkelijkheid. Zijn tests zijn vaak onder ideale omstandigheden.

Misschien dat ik zijn project in de nabije toekomst nog eens ga proberen, maar op lange termijn ga ik ervan uit dat een goeie vm al deze ellende voor mij op gaat lossen. Verder heb ik ook niet de illusie dat java mij de allersnelste code op gaat leveren, hoogstends snel genoege code. En wat kost tegenwoordig hardware? Op een server een nieuwe cpu erin prakken of een reepje geheugen. Een manuur is zo en zoveel duurder dan een beetje hardware.

[ Voor 9% gewijzigd door Alarmnummer op 04-08-2005 00:14 ]


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Macros schreef op woensdag 03 augustus 2005 @ 21:23:
Garbage collection is meestal sneller dan het 1 voor 1 aanvragen en vrijgeven van kleine stukjes geheugen wat vooral gebeurd in C/C++ applicaties. GC heeft ook als voordeel dat het het geheugen kan compacten, zodat het niet enorm gefragmenteerd raakt, wat ook een probleem kan zijn in lang lopende C/C++ applicaties die voortdurend geheugen alloceren en dealloceren.
Aantoonbaar onjuist. Er is namelijk een triviale implementatie van malloc/free die sneller is dan het Java equivalent. Dat is namelijk een malloc implementatie die precies hetzelfde doet als de Java new, en een free() die de pointer in kwestie op een "pseudo-gc" lijst zet. Die adressen op die lijst worden dan door een Java-style GC opgeruimd.

Die lijst is kleiner dan het totale geheugen, en alle pointers zijn zeker vrij van cycles. Het vrijgeven van geheugen uit die lijst is dus zeker net zo efficient als een normale garbage sweep.

Het probleem met fragmentatie is de efficiente detectie ervan. Als je het detecteert kun je het voorkomen of oplossen. Oplossen heeft het voordeel dat het met terugwerkende kracht werkt, maar aangezien het alleen een issue is in langlopende programma's is dat een beperkt voordeel. Overigens is fragmentatie voornamelijk een C probleem, en veel minder een C++ probleem ( met de huidige STL implementaties, SSO, class-specifieke new's... )

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 28-04 14:41

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Macros schreef op woensdag 03 augustus 2005 @ 21:23:
Alle objecten zijn een soort van pointers, het zijn in iedergeval referenties. Ik zie niet zo snel in waarom 'pointers' de performance van C groter kan laten zijn dan Java, als dat het enige verschil zou zijn...
Omdat je in Java alleen pointers kunt maken naar volledige objecten, niet naar een element in een array of naar een functie of gewoon simpelweg een primitive, en je kunt er geen arithmetic op doen. Misschien was ik wat onduidelijk, met pointers bedoel ik idd C/C++ style pointers, niet Java-style references.
Array access and type casting zijn juist die dingen die weggeoptimaliseerd worden door de hedendaagse JIT compilers.
Hoe kan een JIT compiler random access in een array wegoptimaliseren? De check moet gewoon gedaan worden, anders voldoet het niet aan de specs.
Garbage collection is meestal sneller dan het 1 voor 1 aanvragen en vrijgeven van kleine stukjes geheugen wat vooral gebeurd in C/C++ applicaties. GC heeft ook als voordeel dat het het geheugen kan compacten, zodat het niet enorm gefragmenteerd raakt, wat ook een probleem kan zijn in lang lopende C/C++ applicaties die voortdurend geheugen alloceren en dealloceren.
Zie de opmerking van MSalters, en het feit dat ik in mijn vorige post al zei dat het memory model van Java best in C++ te simuleren is, en ook vrij bruikbaar is met gebruik van template classes die zich gedragen als pointers.
Verwijderd schreef op woensdag 03 augustus 2005 @ 22:56:

Oisyn, is dat geen tegenspraak? Je hebt toch -of- een name die een pointer is -of- een name die direct een object is.
Waarom is dat een tegenspraak? C++ heeft toch allebei?
Hoe dan ook, je bewering (zoals ik die hier lees) zou zowieso fout zijn. Java heeft juist -alleen maar- pointers. De enige niet-pointer dingen zijn primitives zoals een int of float. Bedoel je niet dat je in Java geen pointer berekeningen kan doen?
Ja ik had wat duidelijker moeten zijn, zie boven :)
Het feit dat java geen value-type objects heeft is iets wat de taal een zekere in-effecientie kan geven. In diverse gevallen is het gebruik van stack-based allocatie (en deallocatie!) veel goedkoper dan alloceren op de heap. Ook voor het composite pattern kunnen value-type object data members veel efficienter zijn: je object wordt dan gealloceerd als 1 groot block in het geheugen. Bij de gedwongen pointer voor de data members in Java classen, staat je Java object dus altijd ge-scattered in je memory. Een zelfde soort verhaal geldt voor primitieve arrays.
Dit is idd exact wat ik bedoel. Het geheugen is de grote bottleneck, ik zat laatst te profilen op de P4 3.2 GHz hier op m'n werk en stalls van 350 cycles (!!!) bij een cache-miss zijn vrij veelvoorkomend. In die 350 cycles kun je behoorlijk wat doen, en het is dan ook noodzaak om te zorgen dat je de data die je nodig hebt zoveel mogelijk in de L1 cache klaar hebt staan. Dingen als linked lists, trees en arrays van pointers zijn nogal funest als de objecten in de datastructuur gescattered door het geheugen zijn. In onze games zorgen we ervoor dat dit soort structuren hun objecten uit een eigen pool halen, maar het meest belangrijk is nog wel het niet gebruiken van een datastructuur die zogenaamd efficient kan zoeken en inserten/deleten omdat een simpele lineaire search in een array van non-pointers gewoon veel meer cache-friendly is. En insertion/deletion overhead moet je dan maar voor lief nemen. Dit geldt uiteraard tot een bepaalde thresshold van aantal elementen waar het break-even point bereikt wordt, maar die thresshold ligt nog verassend hoog imho.
Wel is het zo dat alleen de wat gevorderde programmeurs voordeel kunnen halen uit stack vs heap allocatie wat performance betreft. Java claimde altijd juist wat makkelijker te willen zijn en daarvoor best wat kracht en performance te willen inleveren.
Ik zie ook zeker wel het nut van java en .Net, maar dat is niet voor performance-critical applicaties zoals games en simulaties, en mensen die beweren dat Java of .Net ooit C++ zal overstijgen in performance geloof ik gewoon niet (de C++ compilers staan immers ook niet stil)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

.oisyn schreef op donderdag 04 augustus 2005 @ 11:00:
[...]
Hoe kan een JIT compiler random access in een array wegoptimaliseren? De check moet gewoon gedaan worden, anders voldoet het niet aan de specs.
Ik neem aan dat je doelt op de array index check, zo ja: In sommige gevallen kan de JIT al zien dat er geen index out of bounds exception kan voorkomen en kunnen de checks ook gewoon weggeoptimaliseerd worden. Vergis je niet in de JIT..

[ Voor 6% gewijzigd door Alarmnummer op 04-08-2005 11:10 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 28-04 14:41

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Natuurlijk kan dat, maar je zegt het zelf al, in sommige gevallen ;)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Verwijderd

.oisyn schreef op donderdag 04 augustus 2005 @ 11:00:
Waarom is dat een tegenspraak? C++ heeft toch allebei?
Mischien dat ik nu niet helemaal duidelijk was. Wat ik bedoelde was dat als Java dus EN geen pointers zou hebben EN geen value-objects, dat je dan dus erg weinig overhoudt in Java :) Dat was de tegenspraak waar ik op wees.

Dat C++ idd allebei heeft (en dat dat een groot voordeel kan zijn) klopt inderdaad, maar stond los van de bedoeling van mijn opmerking. :)

Wat overigens ook een voordeel is van het feit dat je in C++ value objecten hebt, is dat in een samengesteld object je een -echte- "composition" hebt en niet zoals in Java alleen het wat zwakkere (algemenere) "Aggregation". Los van de performance voordelen, heb je bij een composition een sterke notie van ownership en lifetime. (Als je in C++ de 'whole' vernietigd, gaan alle value 'parts' automatisch mee. In Java zullen de poiner 'parts' niet voor GC gemarkeerd worden als er nog een andere entity is die een pointer naar zo'n part bezit).

[ Voor 47% gewijzigd door Verwijderd op 04-08-2005 12:58 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 28-04 14:41

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Verwijderd schreef op donderdag 04 augustus 2005 @ 12:57:

Mischien dat ik nu niet helemaal duidelijk was. Wat ik bedoelde was dat als Java dus EN geen pointers zou hebben EN geen value-objects, dat je dan dus erg weinig overhoudt in Java :) Dat was de tegenspraak waar ik op wees.
Ah ok, maar zoals gezegd vind ik de object references in Java geen pointers ;). Maar idd, zo lijkt het op een tegenspraak.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Macros
  • Registratie: Februari 2000
  • Laatst online: 27-04 11:06

Macros

I'm watching...

.oisyn schreef op donderdag 04 augustus 2005 @ 11:11:
Natuurlijk kan dat, maar je zegt het zelf al, in sommige gevallen ;)
Ik denk eerder bijna alle gevallen...

"Beauty is the ultimate defence against complexity." David Gelernter


  • Macros
  • Registratie: Februari 2000
  • Laatst online: 27-04 11:06

Macros

I'm watching...

Verwijderd schreef op donderdag 04 augustus 2005 @ 12:57:
[...]


Mischien dat ik nu niet helemaal duidelijk was. Wat ik bedoelde was dat als Java dus EN geen pointers zou hebben EN geen value-objects, dat je dan dus erg weinig overhoudt in Java :) Dat was de tegenspraak waar ik op wees.

Dat C++ idd allebei heeft (en dat dat een groot voordeel kan zijn) klopt inderdaad, maar stond los van de bedoeling van mijn opmerking. :)

Wat overigens ook een voordeel is van het feit dat je in C++ value objecten hebt, is dat in een samengesteld object je een -echte- "composition" hebt en niet zoals in Java alleen het wat zwakkere (algemenere) "Aggregation". Los van de performance voordelen, heb je bij een composition een sterke notie van ownership en lifetime. (Als je in C++ de 'whole' vernietigd, gaan alle value 'parts' automatisch mee. In Java zullen de poiner 'parts' niet voor GC gemarkeerd worden als er nog een andere entity is die een pointer naar zo'n part bezit).
Ja, precies, wel mooi voorbeeld. Dus als je een foutje maakt in de lifetimes van je objecten crashed misschien je applicatie in bepaalde situaties, en je hebt niet echt een idee waarom, want je kan het slecht debuggen omdat de dereference en de destructie ongerelateerd zijn en ver van elkaar plaats kunnen vinden, in afstand en tijd....
Wat is dan beter denk je zelf?

Conclusie:
Java is makkelijker programmeren
C++ is krachter en heeft meer mogelijkheden
C++ is in veel gevallen sneller
maar niet in alle gevallen
de JIT compiler wordt elk jaar beter
Orde van grote tussen de snelheid van code voor beide platformen verschillen niet zo enorm dat je Java niet kan gebruiken voor 95-99% van alle gevallen.

"Beauty is the ultimate defence against complexity." David Gelernter


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 28-04 14:41

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Macros schreef op donderdag 04 augustus 2005 @ 15:51:

Ja, precies, wel mooi voorbeeld. Dus als je een foutje maakt in de lifetimes van je objecten crashed misschien je applicatie in bepaalde situaties, en je hebt niet echt een idee waarom, want je kan het slecht debuggen omdat de dereference en de destructie ongerelateerd zijn en ver van elkaar plaats kunnen vinden, in afstand en tijd....
Een beginner ja, een ervaren C++ programmeur heeft dit probleem niet. En nee, hoe vriendelijk een taal is voor beginners vind ik als pro geen belangrijk argument ;). In C++ ga je namelijk nogal anders om met memory management en lifetimes van objects. In de regel heb je dan ook nooit een losse pointer naar een member van een class, maar gewoon een refcounted pointer naar die class instance zelf. Het betreft gewoon een compleet andere manier van managen, en dus kun je Java en C++ op dat gebied niet met elkaar vergelijken. Ook in Java kun je memleaks hebben, en je merkt ze zelfs minder vaak op omdat je er toch al vanuit gaat dat de GC alle zooi voor jou opruimt. Een dangling reference die je dan nog ergens hebt verlies je al snel uit het oog.
Java is makkelijker programmeren
Nee, dit geldt slechts voor de beginnende programmeur. Logisch ook, minder features maakt het al snel makkelijker ;). Daarnaast vergeten veel mensen de kracht van simpele destructors, nog veel handiger dan een garbage collector (ook handig voor exception safe programming).
C++ is krachter en heeft meer mogelijkheden
C++ is in veel gevallen sneller
maar niet in alle gevallen
Wanneer is C++ dan niet sneller, gegeven een goed ontworpen applicatie in zowel C++ als Java? Waar het om gaat is: wanneer is die snelheid belangrijk (dan C++) en wanneer is cross-platform (enterprise) development belangrijk (dan Java) (for the sake of argument doe ik even net of er geen andere talen bestaan ;)). Als geen van beide punten belangrijk zijn moet je gewoon lekker devven in de taal van je eigen keuze.
de JIT compiler wordt elk jaar beter
C++ compilers ook, dus dit is geen argument. Wat je wel krijgt is dat een 10 jaar oude C++ app niet sneller performt dan 10 jaar geleden, terwijl een 10 jaar oude Java app wel sneller performt. Maar ja, dat is natuurlijk een kwestie van op de recompile knop drukken, en applicatie development staat zolang het wordt gebruikt over het algemeen ook niet echt stil.
Orde van grote tussen de snelheid van code voor beide platformen verschillen niet zo enorm dat je Java niet kan gebruiken voor 95-99% van alle gevallen.
Ik denk dat niemand hier beweert dat je überhaupt geen Java moet gebruiken, moot point dus.

[ Voor 9% gewijzigd door .oisyn op 04-08-2005 17:00 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Macros schreef op donderdag 04 augustus 2005 @ 15:51:
[...]
Ja, precies, wel mooi voorbeeld. Dus als je een foutje maakt in de lifetimes van je objecten crashed misschien je applicatie in bepaalde situaties, en je hebt niet echt een idee waarom, want je kan het slecht debuggen omdat de dereference en de destructie ongerelateerd zijn en ver van elkaar plaats kunnen vinden, in afstand en tijd....
Wat is dan beter denk je zelf?
Ik weet niet of je regelmatig in C++ programmeert, maar je members zijn private. Er is dus niemand veraf die pointers naar jouw members heeft, en dus heb je geen crash. Als je toch een object wil sharen, dan doe je dat via een shared_ptr. Dat geeft je een vergelijkbaar effect als Java's GC: een object wordt opgeruimd nadat de laatste pointer ernaar verdwijnt. Het voordeel in C++ is dat het onmiddelijk gebeurt nadat die laatste pointer verdwijnt, en niet op een ongerelateerd moment (handig met debugggen, essentieel als je bijvoorbeeld een temp file wil opruimen).

Overigens zijn lifetime fouten design fouten. In Java heb je meestal memory leaks als je lifetime fouten hebt.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • misfire
  • Registratie: Maart 2001
  • Laatst online: 12-10-2024
Ik wil even beginnen met te benadrukken dat de zogenaamde "VM's" of "managed code" de potentie hebben om over het algemeen sneller te zijn dan een "standaard" omgeving. Ik zal zeker niet beweren dat het nu al zo is, en er zullen natuurlijk altijd uitzonderingen zijn waarin een stukje C++ code in een bepaalde situatie sneller is. Met een managed omgeving zul je theoretisch met veel minder moeite een zeer goed presterende applicatie kunnen maken, die ook nog eens zich beter aanpast aan de beschikbare resources. En theorie en praktijk komen steeds dichterbij.
.oisyn schreef op woensdag 03 augustus 2005 @ 20:38:
Ja en nee. Het hebben van runtime informatie kan enorm schelen, maar een taal als Java is te restrictive om het op te nemen tegen C++. Java heeft nog altijd geen pointers en geen value-type objects, constructies die performance drastisch beinvloeden. Daarnaast wordt er gewoon nog teveel gecontrolleerd (array access, typecasting, niet volledige x87 compatible floating point unit, etc.). Je hebt helemaal gelijk als je zegt dat een JIT compiler beter kan optimaliseren dan een traditionele C++ compiler, je hebt echter imho geen gelijk als Java als taal C++ zou kunnen outperformen.
Java heeft inderdaad geen taal-feature om eigen constructies op de stack te plaatsen. .NET/ C# heeft dit wel. Het niet hebben van een taal-feature wil niet zeggen dat de JIT compiler dit toch niet zou kunnen doen in sommige situaties, er zou kunnen worden besloten na analyse van lifetime en gebruikspatroon dat een object op de stack gealloceerd wordt ipv de heap (Java JIT doet dit nog niet voor zover ik weet). Het gaat mij ook niet om taal X vs taal Y, maar om "voorgecompileerde code" vs "managed code".

Anderen maakten de opmerking ook al, array access checks worden in de meeste situaties weggeoptimaliseerd, typecasting in Java is erg goedkoop. Java checkt inderdaad meer maar kan sommige dingen ook efficienter checken vanwege de extra context.
Onzin, waarom zou een garbage collector performance voordelen hebben? Het is een extra analyse stap die gedaan moet worden, en niet gedaan hoeft te worden in C++, altijd meer overhead dus. En vergeet niet dat je in C++ vrijwel alle side-effects van het memory model van de Java VM kunt simuleren zonder alteveel moeite.
Een garbage collector voorkomt memory fragmentatie en verhoogt lokaliteit van je geheugen, waardoor je minder kans hebt op cache misses (zoals je zelf al aangeeft kan een cache miss veel schelen).

Je hebt inderdaad in C++ ook smart-pointers en malloc varianten die memory fragmentatie voorkomen. Daar hoort ook een stuk administratie bij, en heb je al snel een soort mini-gc. Ik weet ook niet of het helemaal zonder moeite werkt, zeker als je third-party code gaat gebruiken die wellicht uitgaat van een ander geheugen management.

Als je de snelle malloc en de garbage collector naast elkaar zet dan is er opnieuw een verschil in context. De garbage collector weet hoe druk de cpu het heeft, hoeveel geheugen er nog vrij is, of er naar een disk gepaged wordt, of er nog ruimte is in de cache, wat het allocatiepatroon het afgelopen half uur was, enz.

De snelle malloc implementatie zou ook met al dit soort dingen rekening kunnen gaan houden, maar dan begint het ook steeds meer "managed" te worden, en zou het verschil in overhead ook veel kleiner worden. Hetzelfde verhaal geldt ook voor bijvoorbeeld multi-core/multi-processor systemen, verschillen in processor architecturen, enz.

Natuurlijk kun je in C++ allemaal dingen maken die dit gaan controleren en er op gaan optimaliseren. Om dit net zo snel te krijgen zul je ook een vorm van JIT compiler moeten maken, anders zouden er te veel checks gemaakt moeten worden tijdens het uitvoeren van de code.
Ik zie niet in hoe Java meer invloed kan hebben op dingen die door je OS geregeld worden dan dat je in een native taal kunt bewerkstelligen.
Ik kan in Java code schrijven die geoptimaliseerd wordt voor machines en OS-en die nog niet eens bestaan. Als die machines en OS-en wel komen dan hoef je alleen maar een nieuwe versie van Java te pakken en je code wordt automatisch geoptimaliseerd. Ook voor bestaande hardware geldt hetzelfde argument. Ik hoef niet allerlei hardware te kopen, boeken te lezen en me te verdiepen in allerlei soorten optimalisaties. Ik moet alleen weten hoe ik de runtime, JIT compiler en garbage collector kan helpen om code snel uit te voeren.

Natuurlijk wel theoretisch, in de praktijk blijft het handig om te testen en om wel er wat van af te weten. Maar je krijgt echt een heleboel cadeau. De ontwikkeling van hardware is zodanig dat code steeds meer moeite zal moeten doen om het ook nuttig te gebruiken, en ook in die context zullen managed omgevingen steeds beter aansluiten en performen.

Ik zie dat jij bezig bent met een games project. Wist je dat heel lang mensen geen games schreven in C++ omdat het "te traag" was? Het schrijven van snelle managed code vereist oefening, ervaring en inzicht. De gebruikersgroep van C++ en Java is ook nog anders. In het C++ kamp zitten meer mensen die veel weten over hoe een computer van binnen werkt en hoe ze dat snel kunnen(willen) krijgen. In het Java kamp zitten meer mensen die het belangrijker vinden om snel een onderhoudbare applicatie in elkaar te draaien, en denken meer in gele vierkantjes met pijltjes dan in bits en bytes. Daarom zie je als resultaat snelle C++ code en trage Java code. In de meeste gevallen is de echte performance bottleneck is de programmeur. Vandaar ook mijn opmerking: het gezonde verstand is de beste compiler. :)

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

Dit is een zeer interessante thread voor me. Ik begin in september aan m'n thesis en daarvoor moet ik een app schrijven wat een hoop rekenwerk gevoerd zal krijgen. Ik ben onderhand al aan het denken hoe ik dit voor mekaar zal krijgen.

Op dit moment worden die berekeningen in Excel met VBa gedaan en duren ze om en bij een kwartier. (zo heb'k me laten vertellen) Dit natuurlijk om dat de VB-code daar als'k me niet vergis ge-interpreteerd wordt ?
Ik dacht dus op dit moment aan de volgende opstelling: Ik doe alles(gui enz) in C#/.NET en het rekenwerk stuk schrijf ik in een C++ DLL. Nu hebben jullie me natuurlijk aan het twijfelen gebracht (goed gedaan jonges :( _/-\o_ :+ )

Ik dacht tot voorheen altijd dat java en vriendjes oertraag waren. (motto: alles draait lekker op een 10GHz machine :P ) Dit is complete bs, maar C++ heeft nog steeds een mooi performance voordeel tov Java/C#/enz(in het geval dat beide optimaal geschreven zijn). M'n broer vertelde me dinsdag dat een C#/.NET app ruwweg 70% snelheid van een C++ app heeft (kort door de bocht natuurlijk). Dit volgens enkele metingen/reviews/...

Hier zijn al enkele mooie stellingen gepasseerd zoals:
"Een extra CPU-tje in een server steken kost minder dan extra manuren dev-tijd" en nog meer zulks.
Waar ik mijn vakantiejob deed dev'en ze ook enkel in 4GL's (VB.NET) omdat dit gemakkelijk is (en dus waarschijnlijk minder dev-tijd/kosten)

Ik denk dus dat ik m'n eerste opstelling(schrijf eerst alles in C#/.Net, en als het te traag is port je bepaalde stukken naar C++) maar volg... En ik zal dit topic natuurlijk proberen te volgen ;)

@misfire hier net boven ("de beste compiler is het gezond verstand")
dat is denk ik met alles zo. wie meer "weet" over de implementatie/mogelijkheden/... kan die altijd beter benutten/uitbuiten (en kan natuurlijk ook altijd harder tegen de muur lopen als hij een detail vergeet :P )

[ Voor 10% gewijzigd door H!GHGuY op 04-08-2005 22:01 ]

ASSUME makes an ASS out of U and ME


Verwijderd

misfire schreef op donderdag 04 augustus 2005 @ 20:23:
Ik wil even beginnen met te benadrukken dat de zogenaamde "VM's" of "managed code" de potentie hebben om over het algemeen sneller te zijn dan een "standaard" omgeving.
Dat is zeker waar. Daarom bestaat er ook het concept van dynamic native recompilation. Toen ik nog op de universiteit zat deden we hier al onderzoek naar. Dit is heel simpelgezegd een CPU emulator voor CPU A die ook op CPU A draaid met als enige doel om run-time te optimaliseren.
Zie bijvoorbeeld Dynamo: http://citeseer.ist.psu.edu/bala00dynamo.html.
Je hebt inderdaad in C++ ook smart-pointers en malloc varianten die memory fragmentatie voorkomen. Daar hoort ook een stuk administratie bij, en heb je al snel een soort mini-gc.
Sterker nog, je hebt in C++ zelfs complete garbage collectors. In The C++ Programming Language staat ook bijvoorbeeld uitgelegd dat een GC voor C++ geen hack is, maar absoluut in 'de geest van de taal' door een implementatie kan worden toegevoegd. Het verschil met Java is dat je in C++ een keus hebt: helemaal zelf managen, semi-automatisch (smart pointers/ref cnts'), of volledig automatisch (background GC).

Wel is het zo dat de 'bare pointers' in C++ geen support hebben voor object migration in memory (zoals compacting GC's dat doen). Er is echter wel in C++ al langere tijd een trend gaande om standaard minder gebruik te maken van primitieve faciliteiten en meer higher level constructies te gebruiken (eigenlijk net zoals in Java dus). Hieronder valt dus ook het gebruik van de zogenaamde 'bare pointer'. Enkele vooraanstaande C++ figuren hebben ook al wel laten weten kwa pointer gebruik ook zeker naar de C#/Java style 'references' te kijken. Het valt dus zeker te verwachten dat in de volgende C++ versie (zo rond 2015?) het concept van smart pointer nog wat sterker doorgevoerd is. Als 'oefening' hierin kun je al kijken naar de C++/Cli binding van vooraanstaand C++ standaard comitee lid herb sutter in opdracht van MS.

Wat IMHO een performance voordeel van Java is, is dat je dikwijls threads kunt gebruiken in een context waar je in C++ processen zou moeten gebruiken of een andere (async) methode. In Java heb je namelijk de garantie dat een thread die 'crashed' (een non catched exception throwed) niet je hele systeem neerhaalt. In C++ kan een enkele thread het hele systeem neerhalen omdat je mag rommelen met geheugen. 1 thread die bijvoorbeeld een write buiten de bounds van een array doet, of een pointer arithmetic die fout gaat, kan geheugen beschadigen van een andere thread. Voor de veiligheid zou C++ dus naar processen moeten gaan die hun eigen memory space hebben. Echter context switches tussen processen zijn, zoals bekend, veel zwaarder.

[ Voor 18% gewijzigd door Verwijderd op 04-08-2005 22:38 ]


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
misfire schreef op donderdag 04 augustus 2005 @ 20:23:
Een garbage collector voorkomt memory fragmentatie en verhoogt lokaliteit van je geheugen, waardoor je minder kans hebt op cache misses (zoals je zelf al aangeeft kan een cache miss veel schelen).
Een garbage collector voorkomt geen memory fragmentatie. Je beschrijft het gedrag van een memory manager die objecten kan verplaatsen. Dat zat al in Windows 1.0 voor de 8086 (geen grapje!). Alles wat je daar met GlobalAlloc alloceerde kon verschoven worden.
Je hebt inderdaad in C++ ook smart-pointers en malloc varianten die memory fragmentatie voorkomen. Daar hoort ook een stuk administratie bij, en heb je al snel een soort mini-gc. Ik weet ook niet of het helemaal zonder moeite werkt, zeker als je third-party code gaat gebruiken die wellicht uitgaat van een ander geheugen management.
malloc varianten zijn niet zo relevant; C++ gebruikt in principe new/delete. Inderdaad heb je te maken met een behoorlijk complexe memory manager. Dat is niet erg. In die dingen wordt serieus geld gepompt. Microsoft wil niet alleen dat de developers tevreden zijn, maar gebruikt ook memory managers in Windows, Office, SQL Server etc. Dat zijn allemaal applicaties die in benchmarks worden gebruikt. Dat krijg je allemaal gratis.
Als je de snelle malloc en de garbage collector naast elkaar zet dan is er opnieuw een verschil in context. De garbage collector weet hoe druk de cpu het heeft, hoeveel geheugen er nog vrij is, of er naar een disk gepaged wordt, of er nog ruimte is in de cache, wat het allocatiepatroon het afgelopen half uur was, enz.
Pardon? Je denkt dat een VM garbage collector beter kan werken dan de typische OS allocator? Goede kans dat de VM niet eens weet hoeveel CPUs er zijn (OK, op x86/Windows is dat meestal wel het geval ;) ) Een OS allocator kan zelfs integreren met het paging algoritme, zoals in Windows NT.
De snelle malloc implementatie zou ook met al dit soort dingen rekening kunnen gaan houden, maar dan begint het ook steeds meer "managed" te worden, en zou het verschil in overhead ook veel kleiner worden. Hetzelfde verhaal geldt ook voor bijvoorbeeld multi-core/multi-processor systemen, verschillen in processor architecturen, enz.

Natuurlijk kun je in C++ allemaal dingen maken die dit gaan controleren en er op gaan optimaliseren. Om dit net zo snel te krijgen zul je ook een vorm van JIT compiler moeten maken, anders zouden er te veel checks gemaakt moeten worden tijdens het uitvoeren van de code.
Nee. Een goede allocator reageert op de verzoeken om geheugen. In C++ wordt dat expliciet terug gegeven. De memory manager hoeft daarom geen inzicht te hebben in het gebruik; de operator delete calls geven genoeg informatie.
[...]
Ik zie dat jij bezig bent met een games project. Wist je dat heel lang mensen geen games schreven in C++ omdat het "te traag" was?
Dat was .oisyn, maar goed. Ik heb zelfs het verhaal gehoord dat AT&T het niet gebruikte in hun telefooncentrales, terwijl Bjarne toch echt bij Bell Labs werkte? Ook dat was vanwege de snelheid. Dat was in de tijd dat C++ compilers nog niet zo goed waren als vandaag de dag. Een moderne C++ compiler produceert ongeveer even snelle code als een C compiler, en soms sneller (vanwege typesafety en de allocators).

Voor diegenen die inhoudelijk aan wat van mijn claims twijfelen: ik heb met meerdere developers van MSVC++ gesproken over precies dit onderwerp, o.a. Bill Plauger. Da's een erkend expert, en zijn idee is dat allocators nog veel beter kunnen dan nu.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Verwijderd schreef op donderdag 04 augustus 2005 @ 22:32:
[...]
Sterker nog, je hebt in C++ zelfs complete garbage collectors. In The C++ Programming Language staat ook bijvoorbeeld uitgelegd dat een GC voor C++ geen hack is, maar absoluut in 'de geest van de taal' door een implementatie kan worden toegevoegd. Het verschil met Java is dat je in C++ een keus hebt: helemaal zelf managen, semi-automatisch (smart pointers/ref cnts'), of volledig automatisch (background GC).
Klopt, en Boehm (HP) heeft een gratis GC voor C++ beschikbaar.
Wel is het zo dat de 'bare pointers' in C++ geen support hebben voor object migration in memory (zoals compacting GC's dat doen).
Dat is niet zomaar waar. Een compacting GC maakt dat mogelijk door fat pointers te gebruiken. Dat kan net zo goed in C++. Toegegeven, de gemiddelde C++ programmeur hecht meer waarde aan efficiency en minder aan gemak. Bovendien is fragmentatie op andere manieren beter te bestrijden (geheugen fragmenteert niet als blokken van dezelfde grootte uit dezelfde superblok worden gealloceerd, en er weinig kleine allocaties zijn)
Er is echter wel in C++ al langere tijd een trend gaande om standaard minder gebruik te maken van primitieve faciliteiten en meer higher level constructies te gebruiken (eigenlijk net zoals in Java dus). Hieronder valt dus ook het gebruik van de zogenaamde 'bare pointer'. Enkele vooraanstaande C++ figuren hebben ook al wel laten weten kwa pointer gebruik ook zeker naar de C#/Java style 'references' te kijken. Het valt dus zeker te verwachten dat in de volgende C++ versie (zo rond 2015?) het concept van smart pointer nog wat sterker doorgevoerd is. Als 'oefening' hierin kun je al kijken naar de C++/Cli binding van vooraanstaand C++ standaard comitee lid herb sutter in opdracht van MS.
C++0x heeft niet voor niets C++0x. De FDIS (Final Draft International Standard) wordt al in 2006 of 2007 verwacht. Er wordt minder gepolitiekt in ISO dan binnen Java, dus ratificatie zal in 2007 of '08 zijn. Omdat grote delen al beschikbaar zijn (Library TR1) is de verwachting dat implementaties in 2008/2009 volgen.

Aan de andere kant kun je rustig vergeten dan je C#/Java style references krijgt. C++ houdt zijn deterministische destructie. Sterker nog, vanwege C++/CLI zie je in .NET2 en C#2 nu ook deterministische destructie (IDisposable). Er is maar 1 feature waarvoor naar Java gekeken wordt, en dat is het threading model. (Nou ja, er zijn meer features waar naar Java gekeken is maar dat was meestal onder het motto "hoe moet het niet")
Wat IMHO een performance voordeel van Java is, is dat je dikwijls threads kunt gebruiken in een context waar je in C++ processen zou moeten gebruiken of een andere (async) methode. In Java heb je namelijk de garantie dat een thread die 'crashed' (een non catched exception throwed) niet je hele systeem neerhaalt. In C++ kan een enkele thread het hele systeem neerhalen omdat je mag rommelen met geheugen. 1 thread die bijvoorbeeld een write buiten de bounds van een array doet, of een pointer arithmetic die fout gaat, kan geheugen beschadigen van een andere thread. Voor de veiligheid zou C++ dus naar processen moeten gaan die hun eigen memory space hebben. Echter context switches tussen processen zijn, zoals bekend, veel zwaarder.
Dat lijkt me niet zo verstandig. Je applicatie moet aborten als er invarianten onherstelbaar beschadigd zijn. Dat kan door Undefined Behavior in C++, maar net zo goed door bugs in je eigen code. Als je in Java 10 Producers en 1 Consumer thread hebt, en de Consumer gaat dood, wat heb je dan nog aan die andere threads?

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

MSalters schreef op vrijdag 05 augustus 2005 @ 00:23:
Dat lijkt me niet zo verstandig. Je applicatie moet aborten als er invarianten onherstelbaar beschadigd zijn. Dat kan door Undefined Behavior in C++, maar net zo goed door bugs in je eigen code. Als je in Java 10 Producers en 1 Consumer thread hebt, en de Consumer gaat dood, wat heb je dan nog aan die andere threads?
[flame mode]
Hmm tja... meestal zijn runtime exceptions niet zo extreem erg voor normale applicaties. Mensen die schreeuwen dat het het einde van de wereld is, die weten of neit waar ze het over hebben of ze schrijven extreem serieuze softeware. Ik vind trouwens niets zo irritant als een crashende applicatie (vooral bij opensource Linux zooi: deze week weer fijne ervaringen met de Postgresql gui) en dat zou je niet zo snel hebben als dit geschreven was in Java (geef een gebruiker in ieder geval de kans om netjes af te sluiten). Voor normaal applicatie ontwikkeling is imho Java/c# te prefereren boven bijna iedere native taal.

[ Voor 9% gewijzigd door Alarmnummer op 05-08-2005 00:32 ]


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
HIGHGuY schreef op donderdag 04 augustus 2005 @ 21:57:
Ik begin in september aan m'n thesis en daarvoor moet ik een app schrijven wat een hoop rekenwerk gevoerd zal krijgen. Ik ben onderhand al aan het denken hoe ik dit voor mekaar zal krijgen.

Op dit moment worden die berekeningen in Excel met VBa gedaan en duren ze om en bij een kwartier. (zo heb'k me laten vertellen) Dit natuurlijk om dat de VB-code daar als'k me niet vergis ge-interpreteerd wordt ?
Ik dacht dus op dit moment aan de volgende opstelling: Ik doe alles(gui enz) in C#/.NET en het rekenwerk stuk schrijf ik in een C++ DLL. Nu hebben jullie me natuurlijk aan het twijfelen gebracht

Ik dacht tot voorheen altijd dat java en vriendjes oertraag waren. (motto: alles draait lekker op een 10GHz machine :P ) Dit is complete bs, maar C++ heeft nog steeds een mooi performance voordeel tov Java/C#/enz(in het geval dat beide optimaal geschreven zijn). M'n broer vertelde me dinsdag dat een C#/.NET app ruwweg 70% snelheid van een C++ app heeft (kort door de bocht natuurlijk). Dit volgens enkele metingen/reviews/...
Dat zijn inderdaad realistische cijfers. Het enige probleem is dat de cijfers bij rekenwerk wat extremer zijn. Zeker bij hoge nauwkeurigheden (80 bits) is Java extreem traag, maar ook bij 64 bits FP is C++ significant sneller. Matrix wiskunde is helemaal onvergelijkbaar. Daar is C++ concurrerend met FORTRAN, zeker icm de Intel9 vector compiler. Aan de andere kant: 15 minuten VBA code? Zelfs met java moet dat onder de 5 minuten kunnen. Hoeveel eronder is de moeite nog?
Hoe vaak gaat het draaien?

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Alarmnummer schreef op vrijdag 05 augustus 2005 @ 00:27:
[...]
[flame mode]
Hmm tja... meestal zijn runtime exceptions niet zo extreem erg voor normale applicaties. Mensen die schreeuwen dat het het einde van de wereld is, die weten of neit waar ze het over hebben of ze schrijven extreem serieuze softeware. Ik vind trouwens niets zo irritant als een crashende applicatie (vooral bij opensource Linux zooi: deze week weer fijne ervaringen met de Postgresql qui) en dat zou je niet zo snel hebben als dit geschreven was in Java (geef een gebruik in ieder geval de kans om netjes af te sluiten). Voor normaal applicatie ontwikkeling is imho Java/c# te prefereren boven bijna iedere native taal.
Crashes zijn minder, ja. Als je de kans niet krijgt om te saven ben je meestal je werk kwijt. Alleen is ook daar de vraag, gebeurt dat alleen door C++ undefined behavior? Ik moet opbiechten dat ik in niet-kritische code ook wel eens bugjes heb geintroduceerd die een oneindige loop veroorzaken. Pointertje verkeerd, maar wel naar een valide object en je linked list is opeens een cyclic linked list. Dan kun je lang saven, maar het enige resultaat is dat je disk vol is - niet dat je document gesaved is. Daar helpt geen taal tegen - alhoewel talen met built-in linked lists natuurlijk dit soort fouten wel helpen voorkomen.

Voor alle duidelijkheid: in 1995-2000 was VB de meest gebruikte taal voor applicatie ontwikkeling. Zowel Java als C# zijn uitstekende vervangers voor dat specifieke domein. C++ is net zoals C vroeger een taal voor de applicaties waar iets bijzonders mee is. (>4GB data, >100000 gebruikers, >24 uur runtime, <64KB, dat soort dingen.)

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

MSalters schreef op vrijdag 05 augustus 2005 @ 00:36:
[...]
C++ is net zoals C vroeger een taal voor de applicaties waar iets bijzonders mee is. (>4GB data, >100000 gebruikers, >24 uur runtime, <64KB, dat soort dingen.)
[/quote]
Kleiner dan 64kb kan ik me iets bij voorstellen. Bij de rest van de punten minder. Grote clusters met applicatiservers die zijn zeker terug te vinden binnen de javawereld en hierbij geld ook een hoge uptime. Serverside zijn java en c# eigelijk nu wel de talen/platformen.

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

MSalters schreef op vrijdag 05 augustus 2005 @ 00:28:
[...]

Dat zijn inderdaad realistische cijfers. Het enige probleem is dat de cijfers bij rekenwerk wat extremer zijn. Zeker bij hoge nauwkeurigheden (80 bits) is Java extreem traag, maar ook bij 64 bits FP is C++ significant sneller. Matrix wiskunde is helemaal onvergelijkbaar. Daar is C++ concurrerend met FORTRAN, zeker icm de Intel9 vector compiler. Aan de andere kant: 15 minuten VBA code? Zelfs met java moet dat onder de 5 minuten kunnen. Hoeveel eronder is de moeite nog?
Hoe vaak gaat het draaien?
het is een programma voor "dagelijks" gebruik. het is dus aangenaam om in maximaal een minuutje of 2-3 klaar te zijn... Ik zit zelfs nog te denken of ik de ruwe data in de databank opsla, en telkens de afgeleide data te berekenen (het kan namelijk best wel eens zijn dat er later uitbreidingen komen die de basisdata zullen nodig hebben) of als ik de data eenmaal bereken en opsla.

Ik denk eerlijk dat ik die tijd wel naar 30s-1m moet kunnen krijgen in C++ met veel zelf te optimaliseren, door SSE/SSE2/3DNow te gebruiken enz. maar ik ken het algo nog niet...

ASSUME makes an ASS out of U and ME


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Kleiner dan 64kb kan ik me iets bij voorstellen. Bij de rest van de punten minder. Grote clusters met applicatiservers die zijn zeker terug te vinden binnen de javawereld en hierbij geld ook een hoge uptime. Serverside zijn java en c# eigelijk nu wel de talen/platformen.[/quote]
Uptime is iets anders dan runtime. Met runtime bedoel ik dat het verwerken van een enkele job meer dan 24 uur CPU tijd kost. Een gemiddeld webrequest is in een fractie van secondes verwerkt. Bovendien is dat I/O bound. Dan maakt de snelheid van de taal ook nauwelijks uit. De >100000 users slaat meer op 100000 deployed applicaties cq. 100000 lokale gebruikers. Je hebt natuurlijk een goed punt dat je serverside meer flexibiliteit hebt, dan is het een stuk makkelijker om 100000 users te bedienen (mits niet tegelijkertijd natuurlijk)

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

MSalters schreef op vrijdag 05 augustus 2005 @ 09:30:
[...]

Uptime is iets anders dan runtime. Met runtime bedoel ik dat het verwerken van een enkele job meer dan 24 uur CPU tijd kost.
Dat is niet alleen aan c++ voorbehouden. Als ik hier aan het indexeren ben is die server ook tijden zoet. Vind het een beetje een vreemde redenering dat alleen c++ dat zou kunnen. In principe kan java alles wat c++ kan, alleen als je het uiterste uit de kan wilt halen moet je gewoon niet bij Java zij, maar voor veel systemen maakt dat ook niet uit. Kosten van hardware zijn tegenwoordig veel en veel lager dan de kosten van een programmeur en java systemen (.net dito) zijn per definitie sneller te ontwikkelen dan c++ systemen omdat de taal minder mogelijkheden heeft, minder ruimte is voor fouten en er verder gigantisch veel serverside libraries/servers uitzijn. Iemand die echt het uiterste uit de kan wil halen, verklaar ik gek als hij java wil gebruiken. Maar voor het grootste gedeelte van de normale applicaties (die geschreven kan worden in c++ en in Java) verklaar ik mensen gek als ze toch voor c++ kiezen. Deze trend zie je trouwens ook terug in het bedrijfsleven voor webapplicaties. Kijk hoe weinig nog c++ developers worden gevraagd tov .net/java.
Een gemiddeld webrequest is in een fractie van secondes verwerkt. Bovendien is dat I/O bound. Dan maakt de snelheid van de taal ook nauwelijks uit.
Niet alle java applicaties zijn simpele webapplicaties. Ik denk dat je veel te licht erover nadenkt.
De >100000 users slaat meer op 100000 deployed applicaties cq. 100000 lokale gebruikers.
Ik snap niet wat je hiermee bedoelt.

[ Voor 40% gewijzigd door Alarmnummer op 05-08-2005 10:02 ]


Verwijderd

Voor SQL zijn er ook al tooltjes om onder JAVA de boel te optimaliseren, neem nu eens http://www.prevayler.org, deze zorgt ervoor dat Queries soms 1000 x sneller gaan.

Het is een layer over de JBCD geloof ik, dit scheelt toch wel wat in een database toepassing in JAVA.

[ Voor 24% gewijzigd door Verwijderd op 05-08-2005 09:43 ]


Verwijderd

MSalters schreef op vrijdag 05 augustus 2005 @ 00:23:

[crashende threads icm memory corruption]

Dat lijkt me niet zo verstandig. Je applicatie moet aborten als er invarianten onherstelbaar beschadigd zijn. Dat kan door Undefined Behavior in C++, maar net zo goed door bugs in je eigen code. Als je in Java 10 Producers en 1 Consumer thread hebt, en de Consumer gaat dood, wat heb je dan nog aan die andere threads?
Is het niet zo dat dit wel handig is bij een webserver? Als door een bewerking 1 thread een exception gooit ( = 1 request voor 1 user), dan zullen de andere threads daar geen last van hebben, omdat je in het algemeen geen objecten shared tussen users.

In C++ zou je bij gebruik van threads voor de zekerheid de hele AS moeten restarten, bij Java hoeft dat niet. Natuurlijk, als het een serieuze bug is waar elke user vroeg of laat tegen aan loopt, dan moet je die fixen en alsnog herstarten, maar incidentiele dingen belasten alleen een enkele gebruiker.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 28-04 14:41

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Ik reageer slechts even met dingen die nog niet gezegd zijn:
misfire schreef op donderdag 04 augustus 2005 @ 20:23:
Ik wil even beginnen met te benadrukken dat de zogenaamde "VM's" of "managed code" de potentie hebben om over het algemeen sneller te zijn dan een "standaard" omgeving. Ik zal zeker niet beweren dat het nu al zo is, en er zullen natuurlijk altijd uitzonderingen zijn waarin een stukje C++ code in een bepaalde situatie sneller is.
Je originele opmerking was:
Java, .NET en ander JIT compiler constructies hebben hiermee de potentie om de vloer aan te vegen met programmeeromgevingen als C en C++. Verschillende micro-benchmarks laten dat nu al zien
En verderop in je tweede post (waar ik nu op reageer) zeg je nog:
Het gaat mij ook niet om taal X vs taal Y, maar om "voorgecompileerde code" vs "managed code".
Toch heb je het steeds over JIT vs. C/C++. Waarom zou C/C++ niet in een managed omgeving kunnen draaien? Het is natuurlijk niet impliciet dat een C++ app altijd direct naar native code hoeft te compilen. Ik reageerde dan ook puur op Java vs. C++: Java heeft imho te weinig features om ooit de vloer aan te kunnen vegen met C++, of dat nou native of JITed is. En dát was de essentie van mijn post, niet VM vs. native, ook al is de tendens dat Java in een VM draait en C++ naar native machinecode gecompileerd wordt :).
Java heeft inderdaad geen taal-feature om eigen constructies op de stack te plaatsen. .NET/ C# heeft dit wel.
Idd, en daarom vind ik C# ook veel interessanter dan Java, ook door de feature van het toelaten van "unsafe" code. Maar goed, C++/cli komt eraan en dus zal mijn interesse voor C# nooit ver komen ;). Die biedt gewoon the best of both worlds.
Het niet hebben van een taal-feature wil niet zeggen dat de JIT compiler dit toch niet zou kunnen doen in sommige situaties, er zou kunnen worden besloten na analyse van lifetime en gebruikspatroon dat een object op de stack gealloceerd wordt ipv de heap (Java JIT doet dit nog niet voor zover ik weet).
Mja, maar dat vind ik voorlopig nog maar een theoretische gedachtenkronkel. Daarnaast gaat het lang niet alleen over objecten aanmaken op de stack, maar gewoon objecten in-place alloceren in de container: de stack als het een locale variabele of locale array (!!!) betreft, of in het class instance geheugen als het een member van een class betreft. En een value-type zoals een 3d vector of een matrix komt nu specifiek in mij op, die ik in m'n software renderer destijds continu moest new'en. Het punt is dat je door Java's reflection model nooit kunt garanderen dat er geen referentie wordt gemaakt naar die member van de class, en de enige manier om ervoor te zorgen dat dat niet uitmaakt is zorgen dat dat object immutable is, zoals bijvoorbeeld een String (waardoor de VM kan besluiten te copy'en). Dit heeft echter gigantische nadelen op performance als een JIT compiler de optimalisatie van het in-place alloceren niet doet. Natuurlijk kan het allemaal theoretisch, maar ik zie het niet snel gebeuren, if at all.
Wist je dat heel lang mensen geen games schreven in C++ omdat het "te traag" was?
Nou vraag ik me af over hoe lang geleden je het nou precies hebt. C++ kun (of kon althans) je zien als een superset van C++, en derhalve kon je ook C-style code compileren in C++ zonder verschil in snelheid. C++ biedt alleen meer, en idd, zoals MSalters al meldde, vroeger waren de C++ compilers nog niet zo goed in optimaliseren. Nou praat je echter over een hele tijd terug, de reden dat gamedevelopers C++ schuwen is over het algemeen nooit feitelijk snelheid geweest, maar meer het "langzame" imago dat C++ nog had van vroeger en het feit dat gamedevelopers over het algemeen verstokte programmeurs zijn die niet snel iets nieuws zullen ontarmen of iets nieuws aan willen leren :).
Het schrijven van snelle managed code vereist oefening, ervaring en inzicht.
Dat geldt voor alle code. De meeste 'traagheid' is gerelateerd aan het gebruiken van de verkeerde algoritmes of datastructuren voor een bepaald probleem, als je dat goed onder de knie hebt ben je al een heel eind, ongeacht de taal. Als je daarna nog meer wilt zul je je moeten gaan verdiepen in een specifieke taal (C++ comes to mind ;)) op een specifiek platform. En ja, upgraden is vaak goedkoper dan developen, maar helaas gaat dat in de gamesindustrie niet op: je wil een zo groot mogelijke doelgroep bereiken, daarnaast kun je consoles en handhelds niet eens upgraden.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • hobbit_be
  • Registratie: November 2002
  • Laatst online: 04-07-2025
offtopic:
Vraag ik me af in de trend van deze topic hoe het zit met andere 'moderne' talen zoals Python / Ruby op performance vlak (tussen IL / native of voorlopig trager dan IL).

  • misfire
  • Registratie: Maart 2001
  • Laatst online: 12-10-2024
Nogmaals voor mij is het geen discussie Java vs C/C++. Ik haalde C/C++ slechts aan als voorbeeld van een omgeving waarin voorgecompileerde code direct wordt uitgevoerd, vs omgevingen die dynamisch code optimaliseren voor de omgeving (mbv JIT compilers en GC's). Ik had het in mijn eerste reactie ook naast C/C++ over "traditionele compileer processen", "unmanaged code", waarom het verschil aanwezig is in momenten waarop geoptimaliseerd wordt, en waarom dit niet nadelig hoeft te zijn en zelfs imho de toekomst heeft.

Ik zal het er maar op houden dat mijn eerste reactie met iets te veel optimalisaties gelezen werd en er slechts "taal C/C++ is traag" uitkwam oid. :) Nog meer tegeltjeswijsheid: premature optimisation is the root of all evil. :)

@MSAlters:
Een garbage collector voorkomt geen memory fragmentatie. Je beschrijft het gedrag van een memory manager die objecten kan verplaatsen. Dat zat al in Windows 1.0 voor de 8086 (geen grapje!). Alles wat je daar met GlobalAlloc alloceerde kon verschoven worden.
Natuurlijk kan een andere memory manager ook dingen verplaatsen en op die memory fragmentatie oplossen. Het voordeel dat een garbage collector heeft is dat het meerdere technieken kan gebruiken om te voorkomen dat memory fragmentatie optreedt. Het principe van generationele gc's bijvoorbeeld maakt gebruik van de kennis die de gc over lifetime van objecten om aparte gebieden te maken voor long-lived en short-lived objecten. Hetzelfde geldt voor localiteit van geheugen. Een gc heeft meer context.
Pardon? Je denkt dat een VM garbage collector beter kan werken dan de typische OS allocator? Goede kans dat de VM niet eens weet hoeveel CPUs er zijn (OK, op x86/Windows is dat meestal wel het geval ;) ) Een OS allocator kan zelfs integreren met het paging algoritme, zoals in Windows NT.
Nogmaals ik zet hier even twee concepten tegenover elkaar, "goede kans zus en zo" is slechts een argument voor de dagelijkse praktijk. In dit geval zal ik je gerust stellen: Java en .NET weten heus wel hoeveel CPU's er zijn, ook op andere platforms dan Wintel. Wie zegt overigens niet dat de JIT compiler/GC uiteindelijk gewoon de OS allocator zou kunnen gebruiken voor een deel van haar taken? Ik zeg alleen dat de JIT meer kan doen met die extra context informatie over zowel omgeving als (nog te executeren) code.
[Wist je dat heel lang mensen geen games schreven in C++ omdat het "te traag" was?]
Dat was .oisyn, maar goed. Ik heb zelfs het verhaal gehoord dat AT&T het niet gebruikte in hun telefooncentrales, terwijl Bjarne toch echt bij Bell Labs werkte? Ook dat was vanwege de snelheid. Dat was in de tijd dat C++ compilers nog niet zo goed waren als vandaag de dag. Een moderne C++ compiler produceert ongeveer even snelle code als een C compiler, en soms sneller (vanwege typesafety en de allocators).
Mijn opmerking was niet bedoeld om te bewijzen dat C++ traag is, maar om aan te geven dat ervaring en volwassenheid van het platform bepalend kan zijn voor de uiteindelijke perceptie van de performance ervan. Je kunt nu al in sommige gevallen zeggen dat de Java JIT compiler ongeveer even snelle code als een C++ compiler produceert, en soms sneller. Er zijn ook benchmarks op internet te vinden die dit laten zien (alhoewel die net zo goed biased zijn als claims van het C++ compiler team lol). Dat beeld zal in de komende jaren steeds verder verschuiven in het voordeel van managed omgevingen, door de inherente voordelen die ik opnoemde. Dat je ook nog eens robuuster, sneller, makkelijker en flexibeler code kunt schrijven is natuurlijk bijzaak in deze performance discussie. :) Bell labs is een leuk voorbeeld trouwens: wist je dat BEA zeer sterk aan het oprukken is met real time Java voor telefooncentrales, en dit zelfs als hun nieuwe strategische markt op de afgelopen JavaOne presenteerde?
(>4GB data, >100000 gebruikers, >24 uur runtime, <64KB, dat soort dingen.)
Ik werk nu bij een zorgverzekeraar met Java, datasets van een paar 100 gigabytes, duizenden online gebruikers. Voor een beschikbaarheid meer dan >24uur per dag gaan we niet, ;) maar we moeten effectief 99.99% kunnen draaien (is overigens veel meer een operationeel probleem dan een technisch probleem). <64kb, heb je eens op je mobiel gekeken waar die domme mobile games in geschreven worden van 40kb?. De getallen die je noemt zijn zaken waar Java zich prima in kan vinden. Dat je het later weer over duurtijd en deployed units hebt: ook hier laten managed omgevingen juist voordelen zien. Ik zou echt niet weten hoe deze getallen argumenten zijn voor een voorgecompileerde applicatie.

De math performance van Java is trouwens echt niet zo dramatisch, de meeste micro-benches geven aan dat er nu al redelijk dicht bij C++ wordt gescoord, en kijk maar eens naar het pioniers werk van BEA met JRockit en real time enterprise Java. Wel frappant hoe je kunt inschatten hoe een totaal onbekend stuk code in VBA te langzaam is en Java 5 minuten moet kosten. Wie weet kan dit stukje code zelfs in VBA al worden herschreven naar iets wat 100 ms duurt, mits het bovengenoemde gezonde verstand wordt gebruikt. :)

@.oisyn:
Toch heb je het steeds over JIT vs. C/C++. Waarom zou C/C++ niet in een managed omgeving kunnen draaien? Het is natuurlijk niet impliciet dat een C++ app altijd direct naar native code hoeft te compilen. Ik reageerde dan ook puur op Java vs. C++: Java heeft imho te weinig features om ooit de vloer aan te kunnen vegen met C++, of dat nou native of JITed is. En dát was de essentie van mijn post, niet VM vs. native, ook al is de tendens dat Java in een VM draait en C++ naar native machinecode gecompileerd wordt :).
Ik gebruik Java, .NET en C/C++ dus als praktijkvoorbeelden. Zoals ik bovenin al aanhaalde gebruikte ik in mijn eerste post over performance al meer dan één zin om dit toe te lichten, waardoor helaas de onvolledige quote enigszins uit het verband wordt gerukt. Natuurlijk kan C++ ook in een VM draaien, en heeft dan net zo goed de potentie om nog veel sneller te zijn dan voorgecompileerde C++. :) En Hobbit: Python en Ruby zijn ook JIT omgevingen, in deze discussie zou je dus ze kunnen scharen onder dezelfde groep als Java/.NET.
Het punt is dat je door Java's reflection model nooit kunt garanderen dat er geen referentie wordt gemaakt naar die member van de class
Dat is dus het mooie van een JIT compiler, die weet welke code er uitgevoerd gaat worden, en kan dus anders optimaliseren zodra reflection wordt toegepast. Zie bijvoorbeeld de voodoo magic die toegepast wordt voor het gebruik van lokale variabelen in anonieme klasses/delegates. Objecten die normaal op de stack zouden worden gemaakt worden dan ineens op de heap gezet.
Nou praat je echter over een hele tijd terug, de reden dat gamedevelopers C++ schuwen is over het algemeen nooit feitelijk snelheid geweest, maar meer het "langzame" imago dat C++ nog had van vroeger en het feit dat gamedevelopers over het algemeen verstokte programmeurs zijn die niet snel iets nieuws zullen ontarmen of iets nieuws aan willen leren :)
Dat is precies wat ik bedoel: het imago van JIT omgevingen loopt achter op de huidige realiteit. Niet openstaan voor de toekomstige shift en potentie van dit verschil in uitvoeren van code zou ik zeker onverstandig vinden. Ik zal zeker niet zeggen dat Java nu C++ op alle fronten owned en C++ is zeker nu nog de betere keus voor het ontwikkelen van games. Er is zeker een toekomstbeeld waarin dit wel het geval zal zijn (net zoals C++ nu op sommige punten sneller kan zijn dan C, zoals MSAlters aangeeft).

Het schrijven van snelle managed code vereist oefening, ervaring en inzicht: maar wel op punten andere detailkennis dan bijvoorbeeld voorgecompileerde omgevingen. In managed omgevingen zijn allocaties niet altijd evil, en sommige details zijn veel sneller of juist veel trager dan in een unmanaged omgeving. Voor de rest bedoelen we hetzelfde: gezond verstand is de beste performance boost. Als je niet weet wat je doet wordt het altijd traag, of je nu assembler of VBA gebruikt.

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

misfire schreef op vrijdag 05 augustus 2005 @ 21:58:
De math performance van Java is trouwens echt niet zo dramatisch, de meeste micro-benches geven aan dat er nu al redelijk dicht bij C++ wordt gescoord, en kijk maar eens naar het pioniers werk van BEA met JRockit en real time enterprise Java. Wel frappant hoe je kunt inschatten hoe een totaal onbekend stuk code in VBA te langzaam is en Java 5 minuten moet kosten. Wie weet kan dit stukje code zelfs in VBA al worden herschreven naar iets wat 100 ms duurt, mits het bovengenoemde gezonde verstand wordt gebruikt. :)
I don't blame him for that tbh ;)
Ik denk dat de kerel die het geschreven heeft (mijn interne stagebegeleider) et stuk in VBA wel niet in zo'n mate zal verwaarloosd hebben, dat et 150 maal sneller kan ;)

als'k me niet vergis is VBA volledig geinterpreteerd ? dus als je die factor al wegneemt kun je denk ik wel minstens een verdubbeling in snelheid halen... nuja. Als het stuk geschreven is (door mij dan) en de resultaten zijn relevant, dan kan'k ze nog altijd hier posten ;)

ASSUME makes an ASS out of U and ME


  • flowerp
  • Registratie: September 2003
  • Laatst online: 04-02 02:01
Verwijderd schreef op vrijdag 05 augustus 2005 @ 10:21:
Is het niet zo dat dit wel handig is bij een webserver? Als door een bewerking 1 thread een exception gooit ( = 1 request voor 1 user), dan zullen de andere threads daar geen last van hebben, omdat je in het algemeen geen objecten shared tussen users.

In C++ zou je bij gebruik van threads voor de zekerheid de hele AS moeten restarten, bij Java hoeft dat niet.
Zou dat mischien de reden zijn dat C++ de application server markt helemaal heeft gemist? Ik denk dat Java geluk heeft gehad dat ze zich voor zo'n groot gedeelte zijn richten op de server side markt, want dat is toch wel waar ze nu het grootste zijn, naast C# en PHP.

C++ heeft die hele markt links laten liggen. Je kunt C++ wel gebruiken voor webservices, maar eigenlijk zijn er geen of amper web application toepassingen of frameworks voor.

Komt dit nu voornamelijk door het feit dat je in C++ niet met threads kunt werken voor verschillende users?

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

flowerp schreef op zaterdag 06 augustus 2005 @ 13:30:
[...]


Zou dat mischien de reden zijn dat C++ de application server markt helemaal heeft gemist? Ik denk dat Java geluk heeft gehad dat ze zich voor zo'n groot gedeelte zijn richten op de server side markt, want dat is toch wel waar ze nu het grootste zijn, naast C# en PHP.

C++ heeft die hele markt links laten liggen. Je kunt C++ wel gebruiken voor webservices, maar eigenlijk zijn er geen of amper web application toepassingen of frameworks voor.
Ik denk dat c++ de servermarkt heeft gemist omdat de taal te complex en te foutgevoelig is. In java kan je sneller en veiliger produceren dan c++ en verder kun je daardoor ook veel eenvoudiger aan personeel komen.

[edit]
Dito geld trouwens voor .net met c#. Op het moment dat de specifieke specialiteiten van c++ niet van belang zijn, en c#/Java vormen een gelijkwaardig alternatief, dan hebben ze gewoon de voorkeur.

En kijk bij Java eens naar de geweldige lading met serverside tools en specificaties die er bestaan.

[ Voor 17% gewijzigd door Alarmnummer op 06-08-2005 13:38 ]


  • flowerp
  • Registratie: September 2003
  • Laatst online: 04-02 02:01
Alarmnummer schreef op zaterdag 06 augustus 2005 @ 13:35:
[...]

Ik denk dat c++ de servermarkt heeft gemist omdat de taal te complex en te foutgevoelig is. In java kan je sneller en veiliger produceren dan c++ en verder kun je daardoor ook veel eenvoudiger aan personeel komen.
ik weet het niet, te complex en te foutgevoelig zouden immers ook voor andere gebieden gelden. In zijn totaal gezien wordt C++ nog steeds meer gebruikt dan Java. Verder, wat is foutgevoeliger? Wat is complex?

Simpel voorbeeld: in C++ kan ik mijn functies default parameters meegeven. Waarom kan dit niet in Java? Waarom moet ik in Java voor elke default parameter een aparte functie schrijven die telkens de functie met 1 default parameter minder aanroept tot ze op het laatst allemaal bij elkaar komen. Is dat niet complex? Is dat niet foutgevoelig?

Ten tijde dat de web apps in opkomst kwamen moest ik in Java *altijd* als ik iets uit een collection wilde halen casten. Dat is toch niet normaal? Waarom moest dat eigenlijk??? Is dat dan niet complex en foutgevoelig? Zeker als ik ingewikeldere types had, moest ik telkens de plekken opzoeken in mijn code waar ik wat in de collection stopte om het type te achterhalen. Als dat zelf ook weer een collection was, moest ik die ook weer opzoeken. Nu hebben ze dat recent gefixed in Java, maar het spreekt niet echt voor Sun om die bug 8 jaar in Java te laten zitten. :(

En nu hebben ze het gefixed, maar zijn ze weer vergeten typedefs in te voeren. Handig dat je telkens dingen mag schrijven als

Java:
1
2
3
4
5
6
HashMap< String, HashMap< String, ArrayList<Integer>>> createMap() {
   HashMap< String, HashMap< String, ArrayList<Integer>>> myMap 
      = new HashMap< String, HashMap< String, ArrayList<Integer>>>;
   // do something with map
   return myMap;
}


In C++ maak je hier gewoon een makkelijke typedef voor en gebruik je die.

Hoezo complexiteit?

Maar goed, andere dingen in Java zijn wel makkelijker. Enums en variable argumenten zijn echt beter gedaan in Java. In C++ zijn enums niet typesafe en kunnen veel problemen geven. Mijn persoonlijke favoriet in Java is dat classes automatisch in een namespace komen. In C++ moet je met ouderwetse headers werken die letterlijk in je source file gepaste worden. Daarbij moet je nog handmatig constructies zetten om te voorkomen dat je header meerdere keren ge-include wordt.

Mischien dat er hier een expert is die nog een voordeel kan zien in de header werkwijze, maar als iemand die jarenlang in C++ geprogrammeerd heeft kan ik uit ervaring zeggen dat headers redelijk zuigen.
En kijk bij Java eens naar de geweldige lading met serverside tools en specificaties die er bestaan.
Dat is ook een enorm groot voordeel ja, maar dat is niet direct aan de taal (of het concept van de taal) zelf te danken. Tenzij het dus inderdaad zo is dat C++ door enkel en alleen het address space model inderdaad niet geschikt is voor web applicaties.

Trouwens, nog een potentieel performance voordeel van C++ wat ik nog niet het gezien in deze thread is de keuze van de programmeur om een method wel of niet virtual te maken. In Java heb je die keuze niet, een functie is altijd virtual (late binding).

[ Voor 8% gewijzigd door flowerp op 06-08-2005 17:22 ]

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

flowerp schreef op zaterdag 06 augustus 2005 @ 17:04:
[...

ik weet het niet, te complex
C++ is zeker complexer dan java (je hebt tenslotte veel meer bewegingsruimte.

Doordat het complexer is, en doordat c++ geen gc heeft en doordat je moet pointers kan pielen, is c++ gewoon veel foutgevoeliger dan een taal waabij het niet kan. Vergelijk het met een versnellingsbak vs een automaat. Iemand die met een automaat rijd kan zijn versnellingsbak niet kapot maken, maar je moet van een automaat niet verwachten dat hij een auto met een versnellingsbak eruit zal rijden.
en te foutgevoelig zouden immers ook voor andere gebieden gelden. In zijn totaal gezien wordt C++ nog steeds meer gebruikt dan Java. Verder, wat is foutgevoeliger? Wat is complex?
Complex is alles waar een simpeler alternatief voor is :)
Simpel voorbeeld: in C++ kan ik mijn functies default parameters meegeven. Waarom kan dit niet in Java? Waarom moet ik in Java voor elke default parameter een aparte functie schrijven die telkens de functie met 1 default parameter minder aanroept tot ze op het laatst allemaal bij elkaar komen. Is dat niet complex? Is dat niet foutgevoelig?
Mee eens.. Maar dit is een uitzondering. C++ heeft zoveel mogelijkheden die Java niet heeft.. zoveel keuzes te maken... en bij keuzes horen fouten :) Geen keuze geen fouten :P
Ten tijde dat de web apps in opkomst kwamen moest ik in Java *altijd* als ik iets uit een collection wilde halen casten. Dat is toch niet normaal? Waarom moest dat eigenlijk??? Is dat dan niet complex en foutgevoelig? Zeker als ik ingewikeldere types had, moest ik telkens de plekken opzoeken in mijn code waar ik wat in de collection stopte om het type te achterhalen. Als dat zelf ook weer een collection was, moest ik die ook weer opzoeken. Nu hebben ze dat recent gefixed in Java, maar het spreekt niet echt voor Sun om die bug 8 jaar in Java te laten zitten.
Het is geen bug. C++ heeft templates nodig omdat het geen object based class hierarchie heeft. Java heeft dit wel en daarom is generics (templates) noodzaak voor c++ en niet voor Java.

Maar ik ben het met je eens dat geparametriseerde types je code minder foutgevoelig maken. Maar c++ heeft dus zo veel andere mogelijkheden die Java niet heeft.
In C++ moet je met ouderwetse headers werken die letterlijk in je source file gepaste worden. Daarbij moet je nog handmatig constructies zetten om te voorkomen dat je header meerdere keren ge-include wordt.
Precies. vrij foutgevoelig, maar als je hier werkt volgens een vast patroon dan is de pijn nog te overzien.
Trouwens, nog een potentieel performance voordeel van C++ wat ik nog niet het gezien in deze thread is de keuze van de programmeur om een method wel of niet virtual te maken. In Java heb je die keuze niet, een functie is altijd virtual (late binding).
Als er geen sprake is van subclassing dan heb je geen late binding en verder is de JIT vrij intelligent. Verkijk je daar echt niet op.

[edit]
[flame mode]
*Gooit nog ff olie op het vuur* })
The Java is Faster than C++ and C++ Sucks Unbiased Benchmark

[ Voor 6% gewijzigd door Alarmnummer op 06-08-2005 18:28 ]


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
Alarmnummer schreef op zaterdag 06 augustus 2005 @ 17:47:
C++ heeft templates nodig omdat het geen object based class hierarchie heeft. Java heeft dit wel en daarom is generics (templates) noodzaak voor c++ en niet voor Java.
Welnee. C++ heeft void*, Java heeft Object. Ik heb meer dan 1 "generieke" collectie class gezien op basis van void*. Sterker nog, Windows heeft tegenwoordig intrinsics voor threadsafe single-linked lists op basis van void*s. Het probleem daarmee is hetzelfde als met de Java collecties. Templates zijn niet nodig. Alleen, de voordelen die templates bieden zijn zo groot dat zelfs mensen ze zelfs in een achterlijke compiler als VC5 gebruikten. Ik voorspel dat in Java exact hetzelfde gaat gebeuren, vanwege dezelfde voordelen.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
flowerp schreef op zaterdag 06 augustus 2005 @ 17:04:
[...]

Maar goed, andere dingen in Java zijn wel makkelijker. Enums en variable argumenten zijn echt beter gedaan in Java. In C++ zijn enums niet typesafe en kunnen veel problemen geven.
Wordt waarschijnlijk gefixt in C++0x, goede kans dat we de syntax uit C++/CLI overnemen (standaardisatie is idealiter het standariseren van bestaande extensies).
In C++ moet je met ouderwetse headers werken die letterlijk in je source file gepaste worden. Daarbij moet je nog handmatig constructies zetten om te voorkomen dat je header meerdere keren ge-include wordt.

Mischien dat er hier een expert is die nog een voordeel kan zien in de header werkwijze, maar als iemand die jarenlang in C++ geprogrammeerd heeft kan ik uit ervaring zeggen dat headers redelijk zuigen.
Robuustheid bij grote systemen. C++ is ontwikkeld bij AT&T Bell Labs. Bell Labs had een groot probleem met hun 5ESS software. Zelfs op een E10K sun server duurde het bouwen van de code nog 3 dagen. Headers dwingen een scheiding van interface en implementatie af, waardoor je rebuild tijden sterk omlaag kunnen. De meeste build systemen kunnen tegenwoordig dependencies bepalen, en weten op die manier welke dingen niet gecompileerd hoeven te worden. Dankzij headers hoef je dus maar 1 file te compileren als je 1 .cpp verandert. Zelfs een header veranderen kan zonder een full build uit te lokken.

In Java moet je een file parsen om te bepalen of andere files opnieuw gecompileerd moeten worden. Dat is tegenwoordig minder ernstig, sinds de introductie van Program Databases, maarje hebt wel een ingewikkelde toolchain daarvoor nodig.
Dat is ook een enorm groot voordeel ja, maar dat is niet direct aan de taal (of het concept van de taal) zelf te danken. Tenzij het dus inderdaad zo is dat C++ door enkel en alleen het address space model inderdaad niet geschikt is voor web applicaties.
Dat is strikt genomen niet waar; je kunt best een address space model introduceren zodat je C++ code keurig per user gescheiden is. Sterker nog, CGI doet dat. CGI heeft andere problemen, maar bewijst wel dat er geen conceptueel probleem is.
Trouwens, nog een potentieel performance voordeel van C++ wat ik nog niet het gezien in deze thread is de keuze van de programmeur om een method wel of niet virtual te maken. In Java heb je die keuze niet, een functie is altijd virtual (late binding).
Nu is dat een optimalisatie die JIT's goed kunnen uitvoeren.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • flowerp
  • Registratie: September 2003
  • Laatst online: 04-02 02:01
MSalters schreef op zondag 07 augustus 2005 @ 01:29:
[...voordeel headers...]

Robuustheid bij grote systemen. C++ is ontwikkeld bij AT&T Bell Labs. Bell Labs had een groot probleem met hun 5ESS software. Zelfs op een E10K sun server duurde het bouwen van de code nog 3 dagen. Headers dwingen een scheiding van interface en implementatie af, waardoor je rebuild tijden sterk omlaag kunnen.
Ik snap dat het zowieso handig is om je interface en implementatie gescheiden te houden.

Toch zou ik persoonlijk in C++ liever een wat modernere/intelligentere aanpak van dit concept zien. Momenteel is de header in C++ een nogal primitief concept: een filetje* wat 1:1 in je source wordt gepasted. Een header hoeft absoluut niet alleen een class interface te zijn, er kan ook code in staan. Daarbij houdt de compiler niet zelf bij of -van een bepaalde source- een type al defined is, en moet je er zelf (in mijn ogen lelijke) #ifndef MYNAME. etc inzetten. (* de standaard lib headers zonder .h suffix hoeven niet perse een filetje te zijn)

Het zou wellicht handiger zijn als C++ voor de headers net zo'n concept had als Java met het keyword interface. Je hebt dan nog steeds een scheiding tussen interface en implementatie, maar je hebt geen header guards nodig, je class is meteen overal bekend (met een fully qualified name), en er -kan- geen andere rotzooi in komen.

Je zit dan natuurlijk nog wel met het verschil tussen -de- interface van een class (diegene waar maar 1 implementatie van is) en het concept van de generieke/inherited interface (eigenlijk een abstracte base class met alleen pure virtual methods). In Java is -de- interface altijd die van de in-class definities. In C++ kun je net zo goed in-class methods defineren, maar dan worden deze definities via het feit dat headers eigenlijk copy-paste zijn in elke translation unit dubbel gezet. (maar mischien dat moderne compilers dit kunnen detecten?)
Dat is strikt genomen niet waar; je kunt best een address space model introduceren zodat je C++ code keurig per user gescheiden is. Sterker nog, CGI doet dat. CGI heeft andere problemen, maar bewijst wel dat er geen conceptueel probleem is.
Interesant, maar hoe werk dat dan ongeveer? Binnen de OS primitieve 'thread' heb je een shared address space. Via C/C++ pointer arithmetic kun je overal bij binnen je eigen space. Maak je toch aparte spaces, dan heb je eigenlijk geen threads maar processen. Dit kan technisch natuurlijk wel, maar de context switch tussen processen (seperate memory spaces) is veel zwaarder.

Ik had altijd begrepen dat CGI juist veel performance overhead had omdat het noodgedwongen processen moest spawnen ipv threads (maar ik zou me eens in moderne CGI implementaties moeten verdiepen om dit met zekerheid te kunnen zeggen).

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


  • misfire
  • Registratie: Maart 2001
  • Laatst online: 12-10-2024
Alarmnummer schreef op zaterdag 06 augustus 2005 @ 17:47:Doordat het complexer is, en doordat c++ geen gc heeft en doordat je moet pointers kan pielen, is c++ gewoon veel foutgevoeliger dan een taal waabij het niet kan. Vergelijk het met een versnellingsbak vs een automaat. Iemand die met een automaat rijd kan zijn versnellingsbak niet kapot maken, maar je moet van een automaat niet verwachten dat hij een auto met een versnellingsbak eruit zal rijden.
De vergelijking met een versnellingsbak is wel aardig, omdat dit verschil (ook) niet wordt veroorzaakt door de superioriteit van handmatige controle, maar door het verschil in context. Als bestuurder van de auto "weet" ik dat ik die vrachtwagen over 3 tellen wil inhalen en daarom alvast terugschakel. Ik weet dat ik halverwege de bocht gas bij wil geven en schakel voor de bocht al terug. Dat soort dingen weet een automaat niet dus hij kan hier niet op anticiperen.

De extra context die ik als bestuurder heb bepaalt dat ik potentieel beter schakel dan een automaat.

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

misfire schreef op zondag 07 augustus 2005 @ 12:10:
[...]
De vergelijking met een versnellingsbak is wel aardig, omdat dit verschil (ook) niet wordt veroorzaakt door de superioriteit van handmatige controle, maar door het verschil in context. Als bestuurder van de auto "weet" ik dat ik die vrachtwagen over 3 tellen wil inhalen en daarom alvast terugschakel. Ik weet dat ik halverwege de bocht gas bij wil geven en schakel voor de bocht al terug. Dat soort dingen weet een automaat niet dus hij kan hier niet op anticiperen.
Precies. Maar in Grand Turismo rij ik ook met een automaat ;) niet zoveel gezeur en minder stress..
De extra context die ik als bestuurder heb bepaalt dat ik potentieel beter schakel dan een automaat.
Yep. Maar je hebt dus met c++ meer kans een foute beslissingen te nemen en daardoor is het gewoon lastiger om goeie c++ developers te krijgen dan java developers. Voor vee bedrijven is het niet belangrijk dat je met je auto het snelste aankomt, als je maar binnen een acceptabele tijd binnenkomt en de kosten mbt het autorijden niet te hoog zijn. En verder kan iemand in zijn wagen nog zo goed schakelen, tegenover een veel betere auto met automaat heeft hij toch minder kans. En in de enterprise wereld geld vaak dat het goedkoper is om extra hardware bij te plaatsen dan die uren kwijt te zijn aan software ontwikkeling. Ik schrik zelf wel eens van de bedragen.. wow 5.000 euro... wacht eens even.. dat is ca 60 uur werk en dat is echt niet veel tijd. Moet je nagaan wat voor hardware je erbij kan zetten voor 5000 euro.

[ Voor 4% gewijzigd door Alarmnummer op 07-08-2005 13:19 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 28-04 14:41

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Waarom?
en veiliger [produceren dan c++]
Waarom?

"C++ is onveilig" is een fabeltje. Sure, je kunt in C++ onveilig programmeren, maar het mooie is dat je ook veilig kan programmeren. Array bounds checking kun je zo implementeren terwijl jouw code daar niet anders op wordt. Idem voor null pointer cecking bij access, enz. Zoals al eerder in deze draad genoemd zijn er garbage collectors voor C++ die je er zo in kan pluggen. C++ kan dus net zo veilig zijn als Java

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

.oisyn schreef op zondag 07 augustus 2005 @ 14:30:
[...]
Waarom?
[...]
Waarom?

"C++ is onveilig" is een fabeltje.
Je hebt mijn verhaal niet goed begrepen. C++ heeft meer mogelijkheden, dus grotere kans om iets fout te doen. Verder is de pointerproblematiek van c++ een voedingsbodem van fouten. Je moet niet vergeten dat niet alle developers even goed in een taal thuis zijn als jij. Veel developers doen gewoon hun ding van 9 tot 5 en daarna houd het op. En verder maken developers gewoon gebruik van de constructies die in een taal zitten (hoe gevaarlijk het ook is). Dat is ook de hoofdgedachte geweest uit Java. Neem de niet gevaarlijk (gevaarlijk als in versnellingsbak tegenover automaat) features over van c++, haal de meeste onduidelijkheiden weg en introduceer een uniform object model.
Sure, je kunt in C++ onveilig programmeren, maar het mooie is dat je ook veilig kan programmeren. Array bounds checking kun je zo implementeren terwijl jouw code daar niet anders op wordt. Idem voor null pointer cecking bij access, enz. Zoals al eerder in deze draad genoemd zijn er garbage collectors voor C++ die je er zo in kan pluggen. C++ kan dus net zo veilig zijn als Java
Opties opties opties. Bij veel opties heb je een grote kans om een foute te kiezen. En verder is c++ gewoon gevaarlijker door de mogelijkheden van pointer berekeningen: dingen die bij Java gewoon niet mogelijk zijn.

Je moet er dus niet de hele tijd met jouw bril naar kijken. Maar kijk er eens naar uit de optiek van het bedrijf dat de developers in dienst heeft en winst wil maken. Als java en c++ even goeie alternatieven zijn, wat zou jij je developers (die geen goden zijn in c++/java) in willen laten schrijven? Bij mij is de keuze vrij duidelijk..

[ Voor 16% gewijzigd door Alarmnummer op 07-08-2005 15:19 ]


  • flowerp
  • Registratie: September 2003
  • Laatst online: 04-02 02:01
Alarmnummer schreef op zondag 07 augustus 2005 @ 15:09:
Je moet niet vergeten dat niet alle developers even goed in een taal thuis zijn als jij.
Tsja, dat hoor ik andere weer vaak over jou zeggen mbt java ;)
Dat is ook de hoofdgedachte geweest uit Java. Neem de niet gevaarlijk (gevaarlijk als in versnellingsbak tegenover automaat) features over van c++, haal de meeste onduidelijkheiden weg en introduceer een uniform object model.
Opzich heb je wel gelijk peter, maar over wat onduidelijk is valt natuurlijk te twisten. Als we ons alleen even beperken tot de gevaarlijke constructies in C++ dan komt dat eigenlijk maar op 2 dingen neer:

* bald pointers
* primitive array access

Waarbij opgemerk moet worden dat operator [] op een primitive array eigenlijk een afkorting is voor een pointer + offset berekening. Het gebruik van zowel primitive arrays als het gebruik van bald pointers wordt zowieso steeds meer ontmoedigd in C++ voor de 'normale' programmeur. Hiervoor in de plaats komen library containers (bv vector) en smart pointers.


Als we nu eens naar wat andere opvallende dingen kijken die verschillen (verschilde) tussen C++ en Java dan zien we oa:

enums
variable argumenten
(echte) templates
typedefs
default parameters
operator overloading
multiple inheritance
nested scoping ( {int a; { int a; } }
Value types
echte destructors

Zijn deze per definitie unsafe of onduidelijke? Zonder deze constructies maak je een taal inderdaad simpelder. Je kunt code van anderen eerder lezen want er is minder te leren.

Aan de andere kant, maakt het code opzich makkelijker? Ik denk het niet. Het niet overnemen van enums uit C++ had alleen maar tot gevolg dat iedereen rijen static final ints ging maken. Dit werkte alleen maar verwarring op. Sun heeft wel erg lang gewacht met deze aan Java toe te voegen. Je zou bijna zeggen dat ze ze express niet toevoegde om zich maar tegen C++ af te zetten terwijl daar niet echt een reden voor was. (ok, zo kinderachtig zal het wel niet zijn geweest, maar toch...)

Het zelfde geldt voor variable argumenten. Telkens een array aanmaken, vullen en meegeven werkte ook niet super. Het casting verhaal is al genoemd mbt generics.

Waarom heeft Java de typedefs niet overgenomen? Ook die maken het werken met generics veel makkelijker, terwijl het niet unsafe is.

En wat te denken van operator overloading? Werkt voor collections ( [] syntax) en Numbers veel makkelijker: je code ziet er zoveel duidelijker uit en is ook niet unsafe. Sure, het kan misbruikt worden, maar static members in Java (om maar wat te noemen) kunnen ook misbruikt worden.

Multiple inheritance is een krachtig mechanisme, wat inderdaad heel voorzichtig toegepast moet worden. Toch zie ik ook niet veel kwaad en unsafeness hierin (mits met mate en doordacht toegepast natuurlijk).

Nested scoping kan idd verwarring opleveren. Ik weet niet of het nu goed of slecht is dat java dit niet heeft.

Value types zelf zijn ook niet perse unsafe. C# heeft ze ook. De destructie ervan bij het eindigen van de stack kan een probleem zijn als er nog iemand een pointer erna heeft, maar een managed omgeving kan dan een IllegalPointerAccessException oid gooien, net zoals code nu een NPE gooit. Zeker in een managed omgeving hoeven value types dus niet unsafe te zijn. Eigenlijk valt dit nogal samen met destructors. Ook die kunnen ongeldige pointers opleveren, maar een managed omgeving kan dat opvangen zonder dat er undefined behaviour hoeft op te treden.

Als twee-talige programmeur (ik werk zowel veel in C++ als Java) zie ik dat beide talen voordelen hebben. Als Java de betere C++ wil zijn, waarom neemt het dan niet gewoon meer van de goede dingen over die helemaal geen kwaad kunnen?

It's shocking to find how many people do not believe they can learn, and how many more believe learning to be difficult.


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

flowerp schreef op zondag 07 augustus 2005 @ 18:38:
Tsja, dat hoor ik andere weer vaak over jou zeggen mbt java ;)
Afgezien van het feit dat ik redelijk thuis ben in Java, java is gewoon een stuk eenvoudiger. Ik heb voordat ik met java begon ook het een en ander gedaan met c/c++/pascal/delphi maar bij Java was het allemaal erg simpel en er zitten gewoon minder valkuilen in de weg.
Opzich heb je wel gelijk peter, maar over wat onduidelijk is valt natuurlijk te twisten. Als we ons alleen even beperken tot de gevaarlijke constructies in C++ dan komt dat eigenlijk maar op 2 dingen neer:

* bald pointers
* primitive array access
Wel meer dan dat, saskia ;)
-soms een erg cryptische syntax. void* maakt mij geen blij man..
-nare import/header structuur
-pointer problematiek, bv formele argumenten: Gaat het Persoon worden.. of Persoon*.. of Persoon** of &Persoon
-cryptische api`s.
-duidelijke exception afhandeling in Java. In c++ is er veel mogelijk en maakt het veel lastiger te begrijpen
-operator overloading (hiermee kan je rare constructies vormen)
-geen gc (garbage collection is voor standaard toepassing nu eenmaal handig). Dat je in c++ ook op een goeie manier kan werken, twijfel ik niet aan. Maar het is niet de enigste manier om te werken.
-gebrekkige documentatie (c++ heeft niet iets vergelijkbaars zoals Javadoc)
enums sinds in Java 5
variable argumenten sinds in Java 5
(echte) templates sinds in Java 5 (nouja.. echt...)
typedefs
default parameters
operator overloading
multiple inheritance
nested scoping ( {int a; { int a; } }
Value types
echte destructors

Zijn deze per definitie unsafe of onduidelijke? Zonder deze constructies maak je een taal inderdaad simpelder.
De constructies an sich zijn niet unsafe. Maar er zijn zoveel opties. Als er minder opties zijn, kan je minder fout doen en kan je mensen sneller op 1 lijn krijgen. Ik zit ook wel eens tegen java aan te schoppen en wil ook sommige features die je terug vind in c++. Maar voor de meeste systemen die geschreven worden hoef je geen god te zijn. Gewone bedrijven maken ook gewone systemen en als ik directeur was dan had ik ook liever dat mensen met een taal werken waarin je mensen sneller op 1 lijn krijgt.
Je kunt code van anderen eerder lezen want er is minder te leren.
Ja und? Koopt een bedrijf toch niets voor. Wauw.. wij hebben dit en dit uitgevonden.. ja leuk.. maar we zijn wel 2 maand te laat met opleveren. Verder is de taal java vrij 'eenvoudig' maar als je alle j2ee problamtiek erbij betrekt dan trek je weer een enorme beerput met ellende open. Ik ben blij dat ik op taal nivo dan weinig problemen tegenkom bij allerlei j2ee producten. Alles wijst zich op dat nivo vanzelf.
Aan de andere kant, maakt het code opzich makkelijker? Ik denk het niet. Het niet overnemen van enums uit C++ had alleen maar tot gevolg dat iedereen rijen static final ints ging maken. Dit werkte alleen maar verwarring op. Sun heeft wel erg lang gewacht met deze aan Java toe te voegen. Je zou bijna zeggen dat ze ze express niet toevoegde om zich maar tegen C++ af te zetten terwijl daar niet echt een reden voor was. (ok, zo kinderachtig zal het wel niet zijn geweest, maar toch...)
Er zijn idd dingen die al lang in java hadden gemoeten. Maar dat wil niet zeggen dat er daarom alle missende c++ features dan maar goed zijn. C++ is een hele krachtige taal waarbij je tot in de kleinste hoekjes alles kunt configureren, maar dit op een verstandige manier toepassen vergt inzicht en veel programmeurs die hebben dat gewoon niet. Vanuit productie oogput is Java (als Java net zo goed gebruikt kan worden dan c++) een betere taal. Dito geld voor .NET. In Java en .NET kan je met normaal geschool personeel snel software uit de grond stampen.

Persoonlijk vind ik de taal niet zo bijster interessant. Ik vind alle talen ongeveer even kut en achterhaald, maar het gaat om de zaken die erbij zitten. Communities, fora, ide`s, api`s etc. Ik heb bij Java dan vaker het gevoel bij mensen te komen die denken zoals ik. .NET vind ik heel erg onduidelijk en onbegrijpelijk (ik bedoel niet de api`s en taal). En c++.. tja. ik wil ook een boterham verdienen :) Ik kan in Groningen (daar woon ik) zo een aantal bedrijven opnoemen waar ze java developers nodig zijn. Ik weet geen enkel bedrijf in Groningen die c++ developers nodig heeft.

[ Voor 15% gewijzigd door Alarmnummer op 07-08-2005 19:15 ]


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 28-04 14:41

.oisyn

Moderator Devschuur®

Demotivational Speaker

Topicstarter
Alarmnummer schreef op zondag 07 augustus 2005 @ 19:00:
-soms een erg cryptische syntax. void* maakt mij geen blij man..
Terwijl het niet veel anders is dan Object.
-nare import/header structuur
eens :)
-pointer problematiek, bv formele argumenten: Gaat het Persoon worden.. of Persoon*.. of Persoon** of &Persoon
Je bedoelt Persoon&, en hier zijn vrij duidelijke afspraken over te maken.
-cryptische api`s.
Je doelt vast op de standaard C library, ik vind de C++ lib niet zo cryptisch eigenlijk... En de rest (neem de linux API bijvoorbeeld) is natuurlijk niet de schuld van C++.
-gebrekkige documentatie (c++ heeft niet iets vergelijkbaars zoals Javadoc)
Doxygen :)
En c++.. tja. ik wil ook een boterham verdienen :)
Ik ook, en liefst while I'm having fun doing it ;)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

.oisyn schreef op maandag 08 augustus 2005 @ 11:19:
Terwijl het niet veel anders is dan Object.
In principe misschien wel. Maar al deze nuances maken het het complexer. Als er geen keuze is, dan is het minder complex.
Je bedoelt Persoon&, en hier zijn vrij duidelijke afspraken over te maken.
Tja. Iedere developer zal zijn eigen stijl ontwikkelen en bij Java heb je mensen sneller op 1 lijn omdat er minder stijl vormen zijn. Java heeft genoeg variatie om het grootste gedeelte van de software mee te ontwikkelen (het kan dus meestal genoeg) en dat is imho een van de redenen dat het verstandiger is om Java/c# te gebruiken (voor veel projecten) dan c++.
Je doelt vast op de standaard C library, ik vind de C++ lib niet zo cryptisch eigenlijk... En de rest (neem de linux API bijvoorbeeld) is natuurlijk niet de schuld van C++.
Wiens schuld het is maakt niet uit. Het gaat erom of het in de praktijk werkbaar is. Javadoc is in Java erg strak geregeld (dito als bij .NET).
Doxygen :)
Dus ik kan van 99 van de 100 c++ projecten zo een javadoc-achtige documentatie op de site terug vinden? Bij java kan je bijna altijd dit terug vinden.
Ik ook, en liefst while I'm having fun doing it ;)
Ik ook, maar de taal die boeit me dus niet zo, het gaat mij om de inhoud van de opdrachten en de tools waarmee ik kan werken.

[ Voor 3% gewijzigd door Alarmnummer op 08-08-2005 14:51 ]


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 09-04 22:08
flowerp schreef op zondag 07 augustus 2005 @ 10:02:
[...]
Binnen de OS primitieve 'thread' heb je een shared address space. Via C/C++ pointer arithmetic kun je overal bij binnen je eigen space. Maak je toch aparte spaces, dan heb je eigenlijk geen threads maar processen. Dit kan technisch natuurlijk wel, maar de context switch tussen processen (seperate memory spaces) is veel zwaarder.
Je beschrijft nu een "klassiek" memory model. Mijn punt is dat dat niet het enige memory model is. Je kunt in theorie voor elke user een aparte segment descriptor opzetten, en alleen die opnieuw laden. Dat is een veel snellere switch dan een process switch (wel OS support nodig). Een andere methode is om je C++ pointers als 16 bits OS pointer offsets te implementeren. In plaats van OS support heb je dan alleen compiler support nodig, maar je bent beperkt tot 64Kb per-user data. Een derde optie met een modern OS is om de memory space van je C++ app te implementeren als een memory-mapped file, en per user een andere file te mappen. Dat kan zelfs zonder OS of compiler support, maar is iets tricky met threads.
Ik had altijd begrepen dat CGI juist veel performance overhead had omdat het noodgedwongen processen moest spawnen ipv threads (maar ik zou me eens in moderne CGI implementaties moeten verdiepen om dit met zekerheid te kunnen zeggen).
CGI heeft die overhead omdat een standaard compiler een main( ) uitspuugt die uitgaat van een proces. "Fix" de compiler, gebruik een lib die geschikt is voor de webserver context (i.e. zonder threading functionaliteit) en je hoeft geen proces te maken.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • misfire
  • Registratie: Maart 2001
  • Laatst online: 12-10-2024
Alarmnummer schreef op zondag 07 augustus 2005 @ 13:16:
[Handschakelen heeft meer potentie door meer context]
Yep. Maar je hebt dus met c++ meer kans een foute beslissingen te nemen en daardoor is het gewoon lastiger om goeie c++ developers te krijgen dan java developers. Voor vee bedrijven is het niet belangrijk dat je met je auto het snelste aankomt, als je maar binnen een acceptabele tijd binnenkomt en de kosten mbt het autorijden niet te hoog zijn. En verder kan iemand in zijn wagen nog zo goed schakelen, tegenover een veel betere auto met automaat heeft hij toch minder kans.
Uhm, mijn punt was eigenlijk dat een runtime-optimalisatieproces meer context heeft dan een compile-time-optimalisatieproces, en daarom potentieel sneller is. :) De discussie die hierna gestart wordt over de taal C++ laat ik even aan mij voorbij gaan, omdat dit op zichzelf niet zo veel met performance te maken heeft.
En in de enterprise wereld geld vaak dat het goedkoper is om extra hardware bij te plaatsen dan die uren kwijt te zijn aan software ontwikkeling. Ik schrik zelf wel eens van de bedragen.. wow 5.000 euro... wacht eens even.. dat is ca 60 uur werk en dat is echt niet veel tijd. Moet je nagaan wat voor hardware je erbij kan zetten voor 5000 euro.
Dat is inderdaad een reflex die je snel ziet in de Java enterprise wereld: knal er maar meer hardware tegenaan, want dat is goedkoper. Ik ben echter zelf van mening dat een beetje profilen en code-optimalisaties best 20.000 euro mogen kosten als je hiermee 5.000 euro hardware uitspaart (extra hardware zal in de praktijk echter al wel snel in de de 10 duizenden of meer lopen afhankelijk van hoe groot de server is). Er wordt namelijk vaak vergeten dat 80% van de kosten voor een enterprise applicatie worden gemaakt in beheer, en niet in ontwikkeling (het feit dat dit vaak vergeten wordt zal wel een reden zijn voor dit hoge percentage).

Servers moeten beheerd worden, en dat kost geld. Bovendien wordt de topologie van je applicatie complexer, wéér een extra node in het cluster met netwerklijntjes, configuratiestores, hoe ga je om met hardware failures (misschien ook extra uitvalcapaciteit nodig), heb je nog genoeg ruimte in het serverhok, enz. Zomaar een extra server klinkt makkelijk op papier maar bijna nooit zo triviaal.

Mijn persoonlijke ervaring is dat profiling en optimaliseren van code enorme performance winsten oplevert in een relatief korte tijd. Als je die winst hebt dan kun je hiervan profiteren in de volle levensduur van je applicatie en uiteindelijk er veel meer geld mee verdienen. En dan ga je er nog vanuit dat extra hardware je probleem oplost: veel performance problemen zijn een oorzaak van een schaalbaarheidsprobleem en dan heb je zowieso niet veel aan een extra server.

  • Alarmnummer
  • Registratie: Juli 2001
  • Laatst online: 09-07-2024

Alarmnummer

-= Tja =-

misfire schreef op dinsdag 09 augustus 2005 @ 14:21:
[...]
Uhm, mijn punt was eigenlijk dat een runtime-optimalisatieproces meer context heeft dan een compile-time-optimalisatieproces, en daarom potentieel sneller is. :)
Dat kan zijn. Maar de menselijke compiler die c++ developers zijn kunnen nu gewoon op low level nivo het uiterste uit de machine persen. Toen ik nog veel met mijn Prolog compiler bezig was, heb ik met de hand ook nog een hele zooi low level optimalisaties doorgevoerd die de vm gewoon niet uitvoert. Uiteindelijk is het ook een paar honderd keer zo snel gaan draaien (alhoewel de low level optimalisaties niet de grootste rol hebben gespeeld)
Ik ben echter zelf van mening dat een beetje profilen en code-optimalisaties best 20.000 euro mogen kosten als je hiermee 5.000 euro hardware uitspaart (extra hardware zal in de praktijk echter al wel snel in de de 10 duizenden of meer lopen afhankelijk van hoe groot de server is).
Dat ligt er dus aan. Wij schrijven software dat voornamelijk draait op 1 enkele server (of meerdere service waarbij iedere server 1 of meer taken vervuld). Dus het is vrij eenvoudig om die server te upgraden/vervangen. Op dit moment hebben we nog niet veel performance problemen gehad, alhoewel ik nu wel even met een Lucene optimize probleem zit. Maar een paar bankjes geheugen erin rammen zou veel gepiel aan mijn kant besparen.
Er wordt namelijk vaak vergeten dat 80% van de kosten voor een enterprise applicatie worden gemaakt in beheer, en niet in ontwikkeling (het feit dat dit vaak vergeten wordt zal wel een reden zijn voor dit hoge percentage).
TJa.. als je nu 1 langzame of 1 snelle bak beheert.. dat maakt in principe niet uit. Het is een beetje afhankelijk van het soort hardware imho. Als je een of ander cluster moet upgraden.. kan ik me er iets bij voorstellen. Maar als het alleen reepjes geheugen bij plaatsen of eventueel een snellere bak plaatsen is, dan zie ik het probleem niet.
Mijn persoonlijke ervaring is dat profiling en optimaliseren van code enorme performance winsten oplevert in een relatief korte tijd. Als je die winst hebt dan kun je hiervan profiteren in de volle levensduur van je applicatie en uiteindelijk er veel meer geld mee verdienen.
Als jij nu voor een paar honder euro een upgrade moet doen, of je gaat voor een paar duizend euro optimaliseren, dan zie ik daar op lange termijn geen verschil in. Het wil trouwens niet zeggen dat ik totaal niet op performance let, maar soms heb je van die problemen die gewoon beter opgelost kunnen worden door wat geheugen erin te prikken dan ingewikkelde constructies te bedenken. Eigelijk is het bedenken van ingewikkelde constructies (die vaak ontstaan door optimalisatie) nog een extra reden om hardware te upgraden. Jij weet intussen ook wel dat door optimalisatie code meestal er niet beter op wordt.
En dan ga je er nog vanuit dat extra hardware je probleem oplost: veel performance problemen zijn een oorzaak van een schaalbaarheidsprobleem en dan heb je zowieso niet veel aan een extra server.
Je bent niet altijd een extra server nodig. Soms is 1 snellere service de oplossing.

[ Voor 14% gewijzigd door Alarmnummer op 09-08-2005 15:09 ]


  • misfire
  • Registratie: Maart 2001
  • Laatst online: 12-10-2024
Tijdens deze discussie werd eerder het ontbreken van stack-allocaties genoemd als een performance nadeel voor Java. Ik voerde aan dat een VM in principe zelf kan bepalen of stack-allocaties mogelijk zijn en of ze een performance voordeel bieden voor een concrete situatie. Deze stelling wordt binnenkort praktijk: Java 6 gaat de nodige analyse hiervoor bevatten.

  • misfire
  • Registratie: Maart 2001
  • Laatst online: 12-10-2024
Als we toch aan het nabranden zijn, nog een laatste reactie hierop:
Alarmnummer schreef op dinsdag 09 augustus 2005 @ 14:47:
Dat kan zijn. Maar de menselijke compiler die c++ developers zijn kunnen nu gewoon op low level nivo het uiterste uit de machine persen. Toen ik nog veel met mijn Prolog compiler bezig was, heb ik met de hand ook nog een hele zooi low level optimalisaties doorgevoerd die de vm gewoon niet uitvoert. Uiteindelijk is het ook een paar honderd keer zo snel gaan draaien (alhoewel de low level optimalisaties niet de grootste rol hebben gespeeld)
Het probleem van de menselijke compiler is dat het een statische optimalisatie is, die afhangt van een tijdsperiode en de concrete situatie die getest wordt (hardware, load, use-cases). Aangezien dit een theoretische discussie, vergeet ik dan nog even het praktische bezwaar dat een menselijke compiler in de praktijk veel meer kennis en tijd, en dus geld kost, dan een automatische run-time.

Ik kan me de chat-sessie nog herinneren over de Prolog optimalisaties en volgens mij ging dit meer richting het herdesignen van bepaalde onderdelen zodat minder intermediate objecten nodig waren. Zoals je zelf al aangeeft zat het grootste probleem niet in (het ontbreken van) low-level C++ optimalisaties, maar in een design dat op zichzelf erg goed was, maar niet opgewassen was tegen de performance eisen.
Dat ligt er dus aan. Wij schrijven software dat voornamelijk draait op 1 enkele server (of meerdere service waarbij iedere server 1 of meer taken vervuld). Dus het is vrij eenvoudig om die server te upgraden/vervangen. Op dit moment hebben we nog niet veel performance problemen gehad, alhoewel ik nu wel even met een Lucene optimize probleem zit. Maar een paar bankjes geheugen erin rammen zou veel gepiel aan mijn kant besparen.
Mijn punt was dat je het totaal van alle extra kosten van een eventuele upgrade moet meewegen tegen eventuele profile-inspanningen. Als een paar bankjes geheugen het probleem oplost dan gaat mijn verhaal inderdaad niet op, dat is een duidelijk voorbeeld van een simpele upgrade versus een dure profile-sessie. De upgrade-kosten zijn (in de meeste gevallen) meer dan alleen hardware. "Een snellere bak plaatsen" zal al snel betekenen het opnieuw inrichten van een productie-server en een performance-test-server (die moet namelijk dezelfde upgrade krijgen). Als je hierbij optelt de eventuele downtime-schade, noodzakelijke overleggen en discussies, aanpassingen in documentatie...

Misschien dat het voor jouw situatie niet zo'n issue is. De organisatie waar ik zit voert nu een performance-test uit op het mainframe voor een nieuw project. Er is nu al de concessie gedaan dat het project 10 extra cpu's vereist op het mainframe. Aangezien een abonnement op een CPU 3.000 dollar per maand kost, en het product een lifecycle heeft van minimaal 10 jaar, kun je vrij snel uitrekenen hoeveel geld je mag uitgeven aan profilen. In dit project wordt echter geen enkele inspanning gedaan om te profilen, omdat men bij voorbaat al dezelfde fatalistische gedachte heeft dat meer hardware goedkoper is dan optimaliseren.
Het wil trouwens niet zeggen dat ik totaal niet op performance let, maar soms heb je van die problemen die gewoon beter opgelost kunnen worden door wat geheugen erin te prikken dan ingewikkelde constructies te bedenken. Eigelijk is het bedenken van ingewikkelde constructies (die vaak ontstaan door optimalisatie) nog een extra reden om hardware te upgraden. Jij weet intussen ook wel dat door optimalisatie code meestal er niet beter op wordt.
Dat is juist het mooie van een systeem met run-time optimalisaties versus statische optimalisaties: de code hoeft er niet meteen significant ingewikkelder op te worden. Wat ik ook bedoelde met de "run-time helpen" is precies dat: simpele, heldere code schrijven. Dat is niet alleen handiger voor de VM, maar ook handiger voor ontwikkelaars. Mijn ervaring is dat de meeste performance bottlenecks design-issues zijn of gewoon performance bugs die redelijk clean kunnen worden opgelost. Als je "smerige" code moet schrijven dan is dit in een principe een vorm van statische optimalisatie, en daar was ik juist een tegenstander van. In oude JVM's was object pooling bijvoorbeeld een optimalisatie, in moderne JVM's is het meestal alleen maar negatief voor je performance.
Pagina: 1