PDA

Volledige versie bekijken : Heeft dit effect op snelheid van een script?


ClarkNova
%Europe/Berlin %600 %2007, 15:25
Hallo, ben ik weer :)

Wat is beter qua snelheid/geheugen voor een script, doorgeven van een string aan een object om daar iets mee te doen of doorgeven van een ander object met een method om die string te krijgen aan datzelfde script?

Dus, bijv (gesimplificeerd):



var myElement:Element = new Element();
var myStringThing:String = myElement.stringThing;

var myOtherObject:ElementManager = new ElementManager.getInfo(myStringThing);



of



var myElement:Element = new Element();
var myOtherObject:ElementManager = new ElementManager.getInfo(myElement);



met in de ElementManager class de functie, met daarin pas het verkrijgen van die string



public function getInfo(myElement:Element) {
var myStringThing:String = myElement.stringThing;
// rest code
}



Het lijkt mij persoonlijk dat of de eerste methode sneller/beter is, of dat het niet uitmaakt.
Als het niet uitmaakt gebruik ik liever de tweede, aangezien dat wat makkelijker codeert.

Bedankt

Breen
%Europe/Berlin %605 %2007, 15:31
Dat hangt af van wat je ElementManager kan/moet kunnen/doet. Het kan zijn dat je ElementManager helemaal geen zaken heeft met hoe Element nu juist in elkaar zit (ik weet dat dat in deze zin stom klinkt, maar je gebruikt hier ook niet de echte namen veronderstel ik ;)).

Bedenk bij jezelf, of de klasse waar je de string aan gaat meegeven, eigenlijk wel nood heeft aan de kennis over het object dat het binnenkrijgt. Als dat zo is, moet je heel het object meegeven, als dat niet zo is, doe je dat niet.

Om te antwoorden op je vraag, dat maakt volgens mij weinig tot niets uit. Ik denk zelfs dat de eerste methode meer geheugen zal innemen.

ClarkNova
%Europe/Berlin %607 %2007, 15:35
Hmm.. nou het is natuurlijk ook zo dat ik geen verkeerde string binnen wil krijgen, dus het is wel beter qua encapsulatie als de ElementManager alleen maar Elements pakt.
Nou, 2 regels code dus ik ga maar even verder op manier 2 :)

TheDutch
%Europe/Berlin %694 %2007, 17:39
Om te antwoorden op je vraag, dat maakt volgens mij weinig tot niets uit. Ik denk zelfs dat de eerste methode meer geheugen zal innemen.
Het maakt inderdaad niets uit welke van de twee aan de functie wordt meegegeven aangezien er gewoon een referentie meegegeven wordt en niet een kopie van het element. Wel zal er meer geheugen door de applicatie gebruikt worden wanneer je een aparte string variable declareert zoals in optie 1.

Om die rede is optie 2 inderdaad de beste in dit geval :).

Breen
%Europe/Berlin %998 %2007, 00:58
Het maakt inderdaad niets uit welke van de twee aan de functie wordt meegegeven aangezien er gewoon een referentie meegegeven wordt en niet een kopie van het element.

Zijn function parameters zelfs voor value-types dan toch "ByReference"? (Ik vraag het omdat ik het niet weet).

TheDutch
%Europe/Berlin %030 %2007, 01:43
Kan je die vraag nog een keer formuleren, komt me wat onduidelijk over :)

// EDIT: Ik heb zelf nog even getest en ik kan concluderen dat voor complex data types er een referentie wordt gebruikt en voor simple data types er een kopie wordt gebruikt, iets wat ik al eens eerder heb geconcludeerd maar weer vergeten was (het zijn van die weetjes). Daarom zou optie 2 in dit geval zeker beter zijn qua geheugen gebruik.

Mukke
%Europe/Berlin %199 %2007, 05:47
ik dacht dat het wat afstamde van de hogere programeer talen

en alles boven array (en array ook) was passed by reference
en aangezien een string een array van karakters is ...
nouja ik kan helemaal fout zijn maar het klonk logish toen ik deze post begon te schrijven

TheDutch
%Europe/Berlin %275 %2007, 07:37
Je zit inderdaad niet helemaal juist. Een array is een data structure met voor elk element een index, daarom kan een string geen array van karakters zijn. Een string is niets meer dan een opeenvolging (lijst) van karakters :).

Breen
%Europe/Berlin %390 %2007, 10:22
Kan je die vraag nog een keer formuleren, komt me wat onduidelijk over :)

// EDIT: Ik heb zelf nog even getest en ik kan concluderen dat voor complex data types er een referentie wordt gebruikt en voor simple data types er een kopie wordt gebruikt, iets wat ik al eens eerder heb geconcludeerd maar weer vergeten was (het zijn van die weetjes). Daarom zou optie 2 in dit geval zeker beter zijn qua geheugen gebruik.

Sorry voor de onduidelijkheid :). Je beantwoord eigenlijk perfect m'n vraag. Strings (en andere ValueTypes zoals Int's enzovoort) worden doorgegeven "ByValue" waar de waarde dus wordt gekopieerd en dan doorgegeven. Waar ReferenceTypes (Array's, Objects, whatever) worden doorgegeven ByReference (waar enkel hun referentie wordt meegegeven).

Exact wat ik verwachte, maar misschien was dit net iets anders in AVM.

EDIT: om ff verder te gaan op die string & array kwestie die mukke aanhaalde. Je moet eens for..in uitvoeren op een string Dutch, je krijgt dan een sort of, array, index based, per character in de string. Vandaar de verwarring waarschijnlijk.

ClarkNova
%Europe/Berlin %477 %2007, 12:27
Strings (en andere ValueTypes zoals Int's enzovoort) worden doorgegeven "ByValue" waar de waarde dus wordt gekopieerd en dan doorgegeven. Waar ReferenceTypes (Array's, Objects, whatever) worden doorgegeven ByReference (waar enkel hun referentie wordt meegegeven).

Dus als ik dingen wijzig in m'n meegegeven object (byreference) dan wordt dat ook teruggekoppeld?

T

Breen
%Europe/Berlin %479 %2007, 12:30
Teruggekoppeld is niet het juiste woord, in essentie verander je hetzelfde object.

Om heel technisch te worden, variabelen worden opgeslagen op iets wat de "Stack" heet. Een lijst van data, (een soort Array laat ons zeggen) waar alle variabelen op komen. Echter voor ReferenceTypes (objecten, arrays, movieclips) staat op de Stack niet hun waarde, maar een "referentie" naar hun Object op de "Heap".

Bij het meegeven van variabelen, geef je altijd de waarde op de "Stack" mee. Voor nummers & strings enzovoort, is dat dus de echte waarde (vandaar dat je een kopie krijg), voor Reference Types, is dat enkel de referentie (waar je dus over hetzelfde object praat).

Sidenote: als je een ByReference object wilt meegeven byValue, moet je dat momenteel in Flash zelf verzorgen. Ik heb in ons FMS framework daarvoor een kleine methode voorzien, heel simpel te vertalen naar AS3 me dunkt:

/**________________________________________________ __________________________________________________ ___________
* @method cloneObject
* @param oldObject : reference to the object to be cloned
* @description clone an object
*/
CapabilityFramework.prototype.cloneObject = function(oldObject)
{
var newObject = new Object();
for (var i in oldObject)
{
var objType = typeof(oldObject[i])
if (objType.toLowerCase() == "object" || objType.toLowerCase() == "array" )
{
newObject[i] = this.cloneObject(oldObject[i])
}
else
{
newObject[i] = oldObject[i]
}
}
return newObject
}

Mukke
%Europe/Berlin %505 %2007, 13:08
ow ja nu weet ik het weer helemaal
maar kan dit dan ook in flash ?

function telOp(&getal:Number){
getal++;
}

var getal = 2;
telOp(getal);
trace(getal);

geeft dit dan 3 ?
want dit doet me allemaal denken aan C(++) waar je zels de value waarden kunt doorgeven byReference door '&'

Breen
%Europe/Berlin %507 %2007, 13:10
Nope, spijtig genoeg kan je dan niet definiëren of je byVal of byRef wilt doorgeven.

Heel simpel op te lossen natuurlijk door:

function telOp(getal:Number){
return getal++;
}

var getal = 2;
getal = telOp(getal);
trace(getal);

TheDutch
%Europe/Berlin %831 %2007, 20:57
Ik heb in ons FMS framework daarvoor een kleine methode voorzien, heel simpel te vertalen naar AS3 me dunkt:

/**________________________________________________ __________________________________________________ ___________
* @method cloneObject
* @param oldObject : reference to the object to be cloned
* @description clone an object
*/
CapabilityFramework.prototype.cloneObject = function(oldObject)
{
var newObject = new Object();
for (var i in oldObject)
{
var objType = typeof(oldObject[i])
if (objType.toLowerCase() == "object" || objType.toLowerCase() == "array" )
{
newObject[i] = this.cloneObject(oldObject[i])
}
else
{
newObject[i] = oldObject[i]
}
}
return newObject
}

In AS 3 kan je gewoon de bytes kopieëren. Snel, handig, en klein :):

public function copyObject(value:Object):Object
{
var buffer:ByteArray;
var returnValue:Object;

buffer = new ByteArray();
buffer.writeObject(value);
buffer.position = 0;

returnValue = buffer.readObject();

return returnValue;
}

TheDutch
%Europe/Berlin %835 %2007, 21:03
Dus als ik dingen wijzig in m'n meegegeven object (byreference) dan wordt dat ook teruggekoppeld?

T
Ja en nee. Wanneer je de inhoud van het object veranderd dan wel. Echter wanneer je het hele argument in de functie opnieuw set wordt de referentie overschreven en dus niet het werkelijke object waar de referentie naar toe verwees :).

Nope, spijtig genoeg kan je dan niet definiëren of je byVal of byRef wilt doorgeven.
Al zou dit kunnen dan zou hij toch echt de referentie overschrijven en niet het werkelijk element updaten, zoals hier boven omschreven. ActionScript werkt niet met pointers naar delen van het geheugen zoals dit wel kan met bijvoorbeeld C++.

ClarkNova
%Europe/Berlin %455 %2007, 11:56
Ja en nee. Wanneer je de inhoud van het object veranderd dan wel. Echter wanneer je het hele argument in de functie opnieuw set wordt de referentie overschreven en dus niet het werkelijke object waar de referentie naar toe verwees .

Dus stel ik geef een complex object mee, element ofzo en ik zeg dan in de klasse element = null dan verwijder ik alleen de referentie en niet het object, maar als ik doe element.myMethod() dan doet dat wel iets met het object.

Begrijp ik em zo goed? :)

TheDutch
%Europe/Berlin %464 %2007, 12:08
Yep, je begrijpt hem helemaal! :)