Citat:
Men du lyckas ju själv beskriva problemet så borde du ju ha förstått min poäng. Enkapsulering med objekt ger traditionellt mer minnesallokeringar eftersom användare i fler fall behöver ta kopior på data i stället för att direkt accessa.Jag förstår inte riktigt vad du menar med "motvikt till objektorienterad design", inte heller hur mängden specialkod skulle minska eller hur lokala minnespooler kommer in i bilden.
Det finns mycket riktigt ett grundläggande problem som uppstår när man går från att arbeta med POD-typer till klass-typer med konstruktorer och destruktorer. Kompilatorns kontrakt är att den får göra vad den vill med koden så länge det inte påverkar det logiska resultatet av ett väldefinierat program. Eftersom POD-typer är transparenta är det uppenbart för kompilatorn att temporärer av sådan typ kan optimeras bort utan att kontraktet bryts. Temporärer av klass-typ kan däremot ha konstruktorer och destruktorer som antingen är helt okända för kompilatorn, eller i sin tur innehålla anrop med oöverblickbara sidoeffekter. Oöverblickbara sidoeffekter leder till så kallade kompilatorbarriärer, som krafigt begränsar kompilatorns optimeringsmöjligheter.
Move-semantiken löser inte problemet, men det begränsar det. En vektors konstruktor anropar new för att allokera en buffer och en vektors destruktor anropar delete för att frigöra bufferten. Anrop till new och delete är alltid kompilatorbarriärer, men med move-semantik kan en vektor dessutom ha en move-konstruktor som är fri från kompilatorbarriärer då den inte behöver anropa new/delete. Därmed ges kompilatorn möjlighet att optimera bort skapandet av temporära vektorer utan att bryta mot kontraktet.
Det finns mycket riktigt ett grundläggande problem som uppstår när man går från att arbeta med POD-typer till klass-typer med konstruktorer och destruktorer. Kompilatorns kontrakt är att den får göra vad den vill med koden så länge det inte påverkar det logiska resultatet av ett väldefinierat program. Eftersom POD-typer är transparenta är det uppenbart för kompilatorn att temporärer av sådan typ kan optimeras bort utan att kontraktet bryts. Temporärer av klass-typ kan däremot ha konstruktorer och destruktorer som antingen är helt okända för kompilatorn, eller i sin tur innehålla anrop med oöverblickbara sidoeffekter. Oöverblickbara sidoeffekter leder till så kallade kompilatorbarriärer, som krafigt begränsar kompilatorns optimeringsmöjligheter.
Move-semantiken löser inte problemet, men det begränsar det. En vektors konstruktor anropar new för att allokera en buffer och en vektors destruktor anropar delete för att frigöra bufferten. Anrop till new och delete är alltid kompilatorbarriärer, men med move-semantik kan en vektor dessutom ha en move-konstruktor som är fri från kompilatorbarriärer då den inte behöver anropa new/delete. Därmed ges kompilatorn möjlighet att optimera bort skapandet av temporära vektorer utan att bryta mot kontraktet.
Med fler kopieringar får man fler minnesallokeringar.
Med move-semantik kan man minska den totala mängden kopieringar - alltså minska den totala mängden minnesallokeringar.
Den rena exekveringstiden för en extra new/delete motsvarar stora mängder kod och rent kopiösa mängder kodoptimering för att kompensera för. Så i stort sett alla lösningar som får bort en minnesallokering ger en tidsvinst.