/ Forside / Teknologi / Udvikling / PHP / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
PHP
#NavnPoint
rfh 3959
natmaden 3372
poul_from 3310
funbreak 2700
stone47 2230
Jin2k 1960
Angband 1743
Bjerner 1249
refi 1185
10  Interkril.. 1146
Fart fordele ved passing by reference
Fra : Thomas Schulz


Dato : 02-02-02 18:39

I virkeligheden er dette et spørgsmål vedr. PHP engine.

Umiddelbart skulle man jo tror det var en fordel _altid_ at passe fx en
string per reference (da den ellers skulle overføre hver enkelt karakter) -
selv hvis den kaldte funktion ikke ændrer indholdet.

Men der er også muligt at PHP i virkeligheden altid passer per
reference/pointer (altså i det givne eksempel her, også ved en funktion som
ellers ikke er sat til reference_paramaters), og så er det hvis funktionen
ændrer indholdet af strengen at den splittes op i 2 variabler (altså det
originale input som stadigvæk eksisterer efter kaldet til funktionen, og den
værdi der bruges i den kaldte funktion).


Er der nogle der kan henvise mig til en url der beskriver dette nærmere i
php?




Thomas




 
 
Christian Schmidt (02-02-2002)
Kommentar
Fra : Christian Schmidt


Dato : 02-02-02 18:51

Thomas Schulz wrote:
>
> I virkeligheden er dette et spørgsmål vedr. PHP engine.
>
> Umiddelbart skulle man jo tror det var en fordel _altid_ at passe fx en
> string per reference (da den ellers skulle overføre hver enkelt karakter) -
> selv hvis den kaldte funktion ikke ændrer indholdet.
>
> Men der er også muligt at PHP i virkeligheden altid passer per
> reference/pointer (altså i det givne eksempel her, også ved en funktion som
> ellers ikke er sat til reference_paramaters), og så er det hvis funktionen
> ændrer indholdet af strengen at den splittes op i 2 variabler (altså det
> originale input som stadigvæk eksisterer efter kaldet til funktionen, og den
> værdi der bruges i den kaldte funktion).

Jeg tror, du har ret i din teori. En sådan funktionalitet er antydet på
<http://www.phpbuilder.com/mail/php-general/2001041/1769.php>.

Jeg har læst en lidt mere uddybende forklaring for nylig, men den kan
jeg ikke lige finde.

Samme sted mener jeg også at have læst (uden jeg tør lægge hovedet på
blokken), at det (overraskende nok) er langsommere at overføre per
reference. Forklaringen på dette kan jeg dog ikke huske.


Christian

Thomas Schulz (03-02-2002)
Kommentar
Fra : Thomas Schulz


Dato : 03-02-02 18:33

> Jeg tror, du har ret i din teori. En sådan funktionalitet er antydet på
> <http://www.phpbuilder.com/mail/php-general/2001041/1769.php>.
>
> Jeg har læst en lidt mere uddybende forklaring for nylig, men den kan
> jeg ikke lige finde.

Mange tak for linken :).
Hvis du kommer i tanke om den uddybende forklaring link, så skriv endeligt!
:)


Thomas



Anders Johannsen (02-02-2002)
Kommentar
Fra : Anders Johannsen


Dato : 02-02-02 21:52

"Thomas Schulz" <dk_sz@hotmail.com> wrote in message
news:3c5c242c$0$248$edfadb0f@dspool01.news.tele.dk...
> I virkeligheden er dette et spørgsmål vedr. PHP engine.
>
> Umiddelbart skulle man jo tror det var en fordel _altid_ at passe fx en
> string per reference (da den ellers skulle overføre hver enkelt
karakter) -
> selv hvis den kaldte funktion ikke ændrer indholdet.

I praksis har det ingen betydning. Hvis man vil skrive kode hvor hastigheden
er en vigtig faktor, vælger man ikke PHP.

> Men der er også muligt at PHP i virkeligheden altid passer per
> reference/pointer (altså i det givne eksempel her, også ved en funktion
som
> ellers ikke er sat til reference_paramaters), og så er det hvis funktionen
> ændrer indholdet af strengen at den splittes op i 2 variabler (altså det
> originale input som stadigvæk eksisterer efter kaldet til funktionen, og
den
> værdi der bruges i den kaldte funktion).

Jeg har ikke kigget efter i sourcen, men jeg vil tro nej. Uddybende
forklaring
følger:

Simpelt betragtet er et funktionskald en stump kode, der udføres
i et andet namespace. I PHP moduleres dette vha. af en 'stack' og en 'symbol
table'.
En 'stack' er en datastruktur, hvor man kan fjerne og lægge elementer på fra
toppen (sml.
array_push() og array_pop()). En 'symbol table' er et associativt array
('hash table') med
variabelnavne som nøgler og referencer til variablernes værdi som værdier.

Når et funktionskald indledes, oprettes en ny symboltabel hvori funktionens
argumenter
indskrives. Argumenternes værdier kopieres og der oprettes nye referencer.
Ved
'pass by reference' indskrives references direkte i tabellen. Symboltabellen
lægges på toppen
af stacken. Når kaldet er afsluttet, fjernes denne igen, hvorved det
oprindelige 'namespace'
bliver gendannet.

Dit forslag vil kræve, at PHP véd hvornår et udtryk _kan_ forandre en
variabel, samt at
argumenter har en særstatus i forhold til andre variabler (dvs. flere
check).

Mit gæt er, at den øgede kompleksitet ikke nødvendigvis vil resultere i en
højere hastighed.

/A



Thomas Schulz (03-02-2002)
Kommentar
Fra : Thomas Schulz


Dato : 03-02-02 18:32

> I praksis har det ingen betydning. Hvis man vil skrive kode hvor
hastigheden
> er en vigtig faktor, vælger man ikke PHP.

Nu har jeg ganske vist ikke enormt lange strenge, men hvis man havde, ville
det nok gøre en forskel.
Og for iøvrigt, der er da ganske store sider der bruger .php, også nogle for
hvor farten må have en eller anden betydning (hermed ikke sagt at det samme
gælder for mig) i hvert fald :).

> Dit forslag vil kræve, at PHP véd hvornår et udtryk _kan_ forandre en
> variabel, samt at
> argumenter har en særstatus i forhold til andre variabler (dvs. flere
> check).

Ville heller ikke være helt umuligt. Den skulle umiddelt "tracke" lidt
mere.... men..
Hvis PHP enginen var lavet med som formål fra starten ville det ikke have
være noget meget større problem (IMHO).
Jeg har selv oplevet reference counting være nyttigt i nogle andre sprog og
sammehænge.

> Mit gæt er, at den øgede kompleksitet ikke nødvendigvis vil resultere i en
> højere hastighed.

Jeg kan godt se, hvad du mener (omend jeg stadigvæk mener det kommer helt og
andeles an på hvorledes enginen er lavet), og jeg takker for uddybelsen.




mvh
Thomas



Anders Johannsen (03-02-2002)
Kommentar
Fra : Anders Johannsen


Dato : 03-02-02 20:27

On Sun, 03 Feb 2002 18:31:34 +0100, Thomas Schulz wrote:

>> I praksis har det ingen betydning. Hvis man vil skrive kode hvor
> hastigheden
>> er en vigtig faktor, vælger man ikke PHP.
>
> Nu har jeg ganske vist ikke enormt lange strenge, men hvis man havde,
> ville det nok gøre en forskel.

Man kan nok optænke et eksempel, hvor det har en vis betydning. I
praksis går det rimeligt tjept med at kopiere i RAM.

> Og for iøvrigt, der er da ganske store sider der bruger .php, også nogle
> for hvor farten må have en eller anden betydning (hermed ikke sagt at
> det samme gælder for mig) i hvert fald :).

Hvem?

>> Dit forslag vil kræve, at PHP véd hvornår et udtryk _kan_ forandre en
>> variabel, samt at
>> argumenter har en særstatus i forhold til andre variabler (dvs. flere
>> check).
>
> Ville heller ikke være helt umuligt. Den skulle umiddelt "tracke" lidt
> mere.... men..

Det er bestemt muligt at implementere dit forslag. Mit _gæt_ er imidlertid, at
en forbedring i de almindeligste tilfælde ville udeblive.

> Hvis PHP enginen var lavet med som formål fra starten ville det ikke
> have være noget meget større problem (IMHO). Jeg har selv oplevet
> reference counting være nyttigt i nogle andre sprog og sammehænge.

Du bliver nok nødt til at uddybe. PHP benytter 'reference counting'.

/A

Thomas Schulz (04-02-2002)
Kommentar
Fra : Thomas Schulz


Dato : 04-02-02 00:22

> > Hvis PHP enginen var lavet med som formål fra starten ville det ikke
> > have være noget meget større problem (IMHO). Jeg har selv oplevet
> > reference counting være nyttigt i nogle andre sprog og sammehænge.
>
> Du bliver nok nødt til at uddybe. PHP benytter 'reference counting'.

Det har du da netop argumenteret for at den ikke gør..

Anyway, jeg forestillede mig oprindeligt (siden jeg også forestiller mig at
php gemmer værdier i strenge, hvor den så har et felt tilknyttet der holder
styr på typen) at den muligvis lavede reference counting på alt.

Tag fx Delphi.
Der har du en streng.
Den bliver reference counted.

str1 := 'stor file';
str2 := str1;

str1 og str2 peger nu på samme sted (et sted som definerer "reference
count", længde af streng, og så placering af selve karaktererne i strengen).
Hvis jeg så senere str1 ændres decrementes "references count" (det sted hvor
både str og str2 pegede før) fra 2 til 1.

Det vil også sige, hvis du passer en string i Delphi, så passer du bare en
pointer til det område hvor den kan aflæse ovenstående ting.
Derfor er der dog stadig fordele i at passe per reference i Delphi, fx hvis
du har mange e.g. streng argumenter som skal ændres i funktionen (så de kan
bruges senere af kalderen)

Det bruges også ofte i andre sprog.. fx i garbage collectors (jeg mener,
hvis ikke jeg er blevet alt for træt, at Java fx holder en reference count
på alle objekter, og så frigiver dem når reference count ryger ned på 0).



mvh
Thomas



Anders Johannsen (04-02-2002)
Kommentar
Fra : Anders Johannsen


Dato : 04-02-02 10:18

> > Du bliver nok nødt til at uddybe. PHP benytter 'reference counting'.
>
> Det har du da netop argumenteret for at den ikke gør..

Jeg har ikke nævnt det med et ord.

PHP benytter 'reference counting' til at afgøre om et givent objekt kan
frigøres.
Dette checkes typisk når en variabel ikke længere befinder sig i det
aktuelle namespace.

Betragt følgende kode:

<?php

1: function test(&$inner, $other) {
2: $discard = "test";
3: $inner = "Modified";
4: }
5:
6: $outer = "Untouched";
7: $other = "hello";
8: test(&$outer, "hello);

?>

Eksekveringen starter på linje 6. En struktur med følgende informationer
indskrives i symboltabellen.

"outer"
reference count: 1
reference: obj1

På linje 8 indledes funktionskaldet. Det bevirker, jf. tidligere
beskrivelse, at der lægges en ny symboltabel på stacken samt at argumenterne
indskrives i denne. Efter linje 2 ser symboltabellen således ud:

"inner"
reference count: 2
reference: obj1

"other"
reference count: 1
reference: obj2

"discard"
reference count: 1
reference: obj3

På linje 3 ændres værdien af 'inner'. 'inner' refererer til obj1, så det er
denne der bliver ændret. Symboltabellen er uændret.

Når funktionskaldet afsluttes, tages symboltabellen af stacken og den
gennemsøges for strukturer der kan frigøres. Det gøres ved at trække en fra
'reference count'. Efter linje 4 ser symboltabellen således ud

"inner"
reference count: 1
reference: obj1

"other"
reference count: 0
reference: obj2

"discard"
reference count: 0
reference: obj3

Herefter kan obj2 og obj3 altså frigives.

> Det bruges også ofte i andre sprog.. fx i garbage collectors (jeg mener,
> hvis ikke jeg er blevet alt for træt, at Java fx holder en reference count
> på alle objekter, og så frigiver dem når reference count ryger ned på 0).

Garbage collection og reference counting er to forskellige strategier. Ved
reference counting ryddes der typisk op i det øjeblik den sidste reference
forsvindet -- ved GC sker det 'engang imellem'

/A



Thomas Schulz (04-02-2002)
Kommentar
Fra : Thomas Schulz


Dato : 04-02-02 14:13

> Jeg har ikke nævnt det med et ord.

Mmm.. Det er vist rigtigt nok.
Nå.. Ja..
Ellers kan jeg da kun tilslutte mig resten af hvad du skrev.

> Garbage collection og reference counting er to forskellige strategier. Ved
> reference counting ryddes der typisk op i det øjeblik den sidste reference
> forsvindet -- ved GC sker det 'engang imellem'

Ja, ok da, beviser man aldrig skal skrive noget over midnat.
Anyway, nu kommer end mere "entydig" formulering, gc bruger typisk reference
couting (jeg ved det ikke med sikkerhed, det er en antagelse jeg gør mig, nu
har jeg vist taget mine forbehold <g>) for et givent object til at afgøre om
dette skal ryddes op (når gc typisk starter og gør sit arbejde når progammet
er i et idle state).



For i øvrigt, du spurgte hvilke store sider der bruger php (hvis ikke jeg
husker galt der også ;).

http://www.zend.com/zend/aboutphp.php


"
PHP has been in development since 1994. PHP 3, released in June 1998, has
gained rapid popularity, and is now used in Web-related applications by some
of the most prominent organizations such as Mitsubishi, Redhat, Der Spiegel,
MP3-Lycos, Ericsson and NASA
"


mvh.
-Thomas



Søg
Reklame
Statistik
Spørgsmål : 177522
Tips : 31968
Nyheder : 719565
Indlæg : 6408670
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste