Du befindest Dich im Archiv vom ABAKUS Online Marketing Forum. Hier kannst Du Dich für das Forum mit den aktuellen Beiträgen registrieren.

PHP: Teil eines Arrays löschen

Ajax, Hijax, Microformats, RDF, Markup, HTML, PHP, CSS, MySQL, htaccess, robots.txt, CGI, Java, Javascript usw.
Daniela
PostRank 4
PostRank 4
Beiträge: 113
Registriert: 13.09.2004, 20:09
Wohnort: Hamburg

Beitrag von Daniela » 23.08.2006, 23:50

Hallo,

ich brauche von einem sehr großen Array (10.000 Einträge) nur die ersten 20 Einträge. Mit array_splice kann ich alle Einträge > 20 löschen, die Funktion ist aber ziemlich langsam:

array_splice($array, 20);

Gibt es dazu eine schnellere Alternative?

Liebe Grüße,
Daniela

Anzeige von ABAKUS

von Anzeige von ABAKUS »

SEO Consulting bei ABAKUS Internet Marketing
Erfahrung seit 2002
  • persönliche Betreuung
  • individuelle Beratung
  • kompetente Umsetzung

Jetzt anfragen: 0511 / 300325-0.


Anonymous

Beitrag von Anonymous » 24.08.2006, 00:40

schau dir mal array_shift() an.....

hmm.... Mädel, ich muss sagen, deine Fragen hier, besonders so um diese Uhrzeit, haben so langsam meine Neugier geweckt.... was haste vor?

Irgendwie habe ich den Verdacht, dass man dein Vorhaben irgendwie simpler umsetzen kann....

schick mir ma per PN deine ICQ UIN...

Daniela
PostRank 4
PostRank 4
Beiträge: 113
Registriert: 13.09.2004, 20:09
Wohnort: Hamburg

Beitrag von Daniela » 24.08.2006, 02:18

array_shift nummeriert doch jedes mal neu durch, das kann nicht optimal sein. aber ich probiers trotzdem mal aus.

Anonymous

Beitrag von Anonymous » 24.08.2006, 03:04

Daniela hat geschrieben:array_shift nummeriert doch jedes mal neu durch, das kann nicht optimal sein. aber ich probiers trotzdem mal aus.
denk da mal mehr technisch, nicht bildlich.... ein PC kennt nur 0 und 1, sonst nix.... stell dir das eher als ein riesiges regal vor..... du denkst an "neu durchnummerieren" aber es muss doch nur das aktuelle "Regalfach" ausgegeben werden und das nächste "Regalfach" als neues erstes gemerkt werden..... mal bildlich dargestellt... :wink:

und auch spielt die Programmierung einer Funktion eine Rolle, viele lassen sich auf zig verschieden Arten lösen... und je "wichtiger" umso mehr wird darauf geachtet dass sie schnell ist....

genaues bringt dir also nur ein wirklicher livetest.....

Caesar
PostRank 4
PostRank 4
Beiträge: 159
Registriert: 22.02.2004, 00:05
Wohnort: Hanau

Beitrag von Caesar » 24.08.2006, 03:19

Wie wäre es eine Schleife laufen zu lassen?
https://www.coder-forum.eu

Was wir wissen ist ein Tropfen, was wir nicht wissen ein Ozean

Suche Linkpartner zum Thema Führerschein, Auto und Programmieren.

Anonymous

Beitrag von Anonymous » 24.08.2006, 03:23

Caesar hat geschrieben:Wie wäre es eine Schleife laufen zu lassen?
naja... das setzt die Verwendung von array_shift() vorraus... :roll:

Southmedia
PostRank 10
PostRank 10
Beiträge: 7322
Registriert: 20.07.2003, 19:56

Beitrag von Southmedia » 24.08.2006, 04:06

net(t)worker, sowas in die Richtung?

Code: Alles auswählen

for &#40;$i = 1; $i <= 20; $i++&#41; &#123;
    $result&#91;&#93; = array_shift&#40;$array&#41;;
&#125;
array_slice wäre noch eine Alternative:

Code: Alles auswählen

$result = array_slice&#40;$array, 0, 20&#41;;

Southmedia
PostRank 10
PostRank 10
Beiträge: 7322
Registriert: 20.07.2003, 19:56

Beitrag von Southmedia » 24.08.2006, 04:26

Ich habs schnell verglichen für ein Array mit 5000 Werten. Eine Durchlauf als Beispiel:

array_shift 65ms
array_splice 33ms
array_slice 0,1ms

Das Verhältnis war bei mehreren Durchläufen gleich, die effektiven ms-Werte varrierten je nach sonstiger Last.

Getestete Datei:

Code: Alles auswählen

<?php

$array = array&#40;'foo', 'bar', ...&#41;;

function slice&#40;$array&#41; &#123;
	$result = array_slice&#40;$array, 0, 20&#41;;
	return $result;
&#125;

function splice&#40;$array&#41; &#123;
	array_splice&#40;$array, 20&#41;; 
	return $array;
&#125;

function shift&#40;$array&#41; &#123;
	$result = array&#40;&#41;;
    for &#40;$i = 1; $i <= 20; $i++&#41; &#123;
        $result&#91;&#93; = array_shift&#40;$array&#41;;
    &#125;
    return $result;
&#125;

$array1 = $array;
$result1 = shift&#40;$array1&#41;;

$array2 = $array;
$result2 = splice&#40;$array2&#41;;

$array3 = $array;
$result3 = slice&#40;$array3&#41;;

?>

Anonymous

Beitrag von Anonymous » 24.08.2006, 06:48

Southmedia hat geschrieben: array_shift 65ms
array_splice 33ms
array_slice 0,1ms
sind doch schon nette Unterschiede.....

nur ich frage mich irgendwie wieso man ein array mit mehreren 10.000 Elementen hat, wenn man dann nur 20 braucht.... kann man das nicht anders machen?

Daniela
PostRank 4
PostRank 4
Beiträge: 113
Registriert: 13.09.2004, 20:09
Wohnort: Hamburg

Beitrag von Daniela » 24.08.2006, 11:47

Danke southmedia, dann werde ich wohl array_slice nutzen. Ist ja doch um einiges schneller. Hätte ich nicht gedacht.
nur ich frage mich irgendwie wieso man ein array mit mehreren 10.000 Elementen hat, wenn man dann nur 20 braucht.... kann man das nicht anders machen?
Im Script wird für mehrere Einträge einer Tabelle etwas gemacht, es gibt also eine Schleife die x mal ausgeführt wird. Jedes mal brauche ich nun 20 zufällige Einträge aus einer anderen Datenbank zur Weiterverarbeitung. Mache ich das jeweils durch ein SELECT ORDER BY RAND() braucht das massiv Zeit und Speicher. Stattdessen führe ich vor der Schleife einmal ein SELECT auf die komplette Tabelle aus und shuffle dann bei jedem Schleifendurchgang eine Kopie des Arrays und nehme die ersten 20 Einträge davon. Viel schneller. Und gar nicht so doof, oder?

Liebe Grüße,
Daniela

Anonymous

Beitrag von Anonymous » 24.08.2006, 15:13

Ok... hört sich sinnvoll an... wenn du die 20 Daten mehrmals brauchst...

wenn ich einmal zufällig 20 daten aus einer DB brauche ermittel ich erst wieviel Datensätze für die Abfrage in der db vorhanden sind und hole mir dann 20 mal jeweils einen mit LIMIT Zufallszahl,1

aber wenn du die daten mehrmals benötigst ist es ggf. nicht sinnvoll...

Southmedia
PostRank 10
PostRank 10
Beiträge: 7322
Registriert: 20.07.2003, 19:56

Beitrag von Southmedia » 24.08.2006, 16:00

In dem Zusammenhang vielleicht auch interessant:
https://jan.kneschke.de/projects/mysql/order-by-rand/

Southmedia
PostRank 10
PostRank 10
Beiträge: 7322
Registriert: 20.07.2003, 19:56

Beitrag von Southmedia » 25.08.2006, 19:06

net(t)worker, dein Beitrag hat mich noch auf eine vierte Idee gebracht. Nimmt man nämlich oben jeweils noch ein shuffle() auf das große Array hinzu, zieht das natürlich die Performance runter. Da kann es wirklich besser sein, 20 zufällige Einträge aus dem immer gleich sortierten Array zu nehmen:

Code: Alles auswählen

function forschleife&#40;$array&#41; &#123;
	$count = count&#40;$array&#41;;
    $count = $count-1;

    $result = array&#40;&#41;;

    for &#40;$i = 1; $i <= 20; $i++&#41; &#123;
        
        $zufall = rand&#40;0,$count&#41;;
        $result&#91;&#93; = $array&#91;$zufall&#93;;
        
    &#125;
    return $result;
&#125;
Also nun mal die Zeiten für randomized Values:

array_splice 179ms
array_shift 143ms
array_slice 11ms
forschleife 1,3 ms

Interessant was man da alles rausholen kann.

Anonymous

Beitrag von Anonymous » 25.08.2006, 19:29

müssteste dann aber jeweils überprüfen ob du ein Element nicht zufällig 2 mal geholt hast

Code: Alles auswählen

function whileschleife&#40;$array&#41; &#123;
	$count = count&#40;$array&#41;;
    $count = $count-1;

    $result = array&#40;&#41;;
    $result2=array&#40;&#41;;
    $i=0;
    while &#40;$i < 20&#41; &#123;
        
        $zufall = rand&#40;0,$count&#41;;
        if &#40;!in_array&#40;$zufall,$result2&#41;
        &#123;
             $result&#91;&#93; = $array&#91;$zufall&#93;;
             $result2&#91;&#93; = $zufall;
             $i++;
         &#125;
    &#125;
    return $result;
&#125;
und beim Aufruf sollte man ggf. auch nochmal testen ob es jetzt besser ist das array direkt zu übergeben oder ggf. nur einen Verweis auf das originalarray, dies wird durch die Funktion ja nicht verändert...

oder ggf. nur den Namen des Arrays übergeben und dann direkt aufs originalarray zugreifen::

Code: Alles auswählen

function whileschleife&#40;$array&#41; &#123;
   global $$array;
   ....
   ....
   $result&#91;&#93; = $$array&#91;$zufall&#93;;
   ....
   ....
und dann einfach so aufrufen:

Code: Alles auswählen

$grosses_Array = array&#40;'a','b',.........&#41;;

$zufall_array= whileschleife&#40;'grosses_array'&#41;;

Southmedia
PostRank 10
PostRank 10
Beiträge: 7322
Registriert: 20.07.2003, 19:56

Beitrag von Southmedia » 25.08.2006, 20:38

müssteste dann aber jeweils überprüfen ob du ein Element nicht zufällig 2 mal geholt hast
Stimmt, wenn die Werte definitiv nur einmalig vorkommen dürfen. Das hatte ich vergessen. Danke für die Anmeldung.

Ich habe die Funktion whileschleife (korrigiert, waren kleine Fehler drin) auch mal kurz gecheckt: 2,2ms.

Code: Alles auswählen

function whileschleife&#40;$array&#41; &#123;
    $count = count&#40;$array&#41;;
    $count = $count-1;

    $result = array&#40;&#41;;
    $result2 = array&#40;&#41;;
    $i=0;
    while &#40;$i < 20&#41; &#123;
       
        $zufall = rand&#40;0,$count&#41;;
        if &#40;!in_array&#40;$zufall,$result2&#41;&#41; &#123;
             $result&#91;&#93; = $array&#91;$zufall&#93;;
             $result2&#91;&#93; = $zufall;
             $i++;
        &#125;
    &#125;
    return $result;
&#125;
Nett übrigens dass du die Schlüssel in $result2 speicherst, ich hätte wohl aus Dummheit die Werte genommen.

Tatsächlich sollte man bei den beiden eigenen Funktionen auch noch bezüglich Referenzen und Originalarray überprüfen. Schreibst die Funktionen schnell um?

Antworten
  • Vergleichbare Themen
    Antworten
    Zugriffe
    Letzter Beitrag