Seite 1 von 2
PHP: Teil eines Arrays löschen
Verfasst: 23.08.2006, 23:50
von Daniela
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
Verfasst:
von
SEO Consulting bei
ABAKUS Internet Marketing Erfahrung seit 2002
- persönliche Betreuung
- individuelle Beratung
- kompetente Umsetzung
Jetzt anfragen:
0511 / 300325-0.
Verfasst: 24.08.2006, 00:40
von net(t)worker
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...
Verfasst: 24.08.2006, 02:18
von Daniela
array_shift nummeriert doch jedes mal neu durch, das kann nicht optimal sein. aber ich probiers trotzdem mal aus.
Verfasst: 24.08.2006, 03:04
von net(t)worker
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...
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.....
Verfasst: 24.08.2006, 03:19
von Caesar
Wie wäre es eine Schleife laufen zu lassen?
Verfasst: 24.08.2006, 03:23
von net(t)worker
Caesar hat geschrieben:Wie wäre es eine Schleife laufen zu lassen?
naja... das setzt die Verwendung von array_shift() vorraus...

Verfasst: 24.08.2006, 04:06
von Southmedia
net(t)worker, sowas in die Richtung?
Code: Alles auswählen
for ($i = 1; $i <= 20; $i++) {
$result[] = array_shift($array);
}
array_slice wäre noch eine Alternative:
Verfasst: 24.08.2006, 04:26
von Southmedia
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('foo', 'bar', ...);
function slice($array) {
$result = array_slice($array, 0, 20);
return $result;
}
function splice($array) {
array_splice($array, 20);
return $array;
}
function shift($array) {
$result = array();
for ($i = 1; $i <= 20; $i++) {
$result[] = array_shift($array);
}
return $result;
}
$array1 = $array;
$result1 = shift($array1);
$array2 = $array;
$result2 = splice($array2);
$array3 = $array;
$result3 = slice($array3);
?>
Verfasst: 24.08.2006, 06:48
von net(t)worker
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?
Verfasst: 24.08.2006, 11:47
von Daniela
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
Verfasst: 24.08.2006, 15:13
von net(t)worker
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...
Verfasst: 24.08.2006, 16:00
von Southmedia
Verfasst: 25.08.2006, 19:06
von Southmedia
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($array) {
$count = count($array);
$count = $count-1;
$result = array();
for ($i = 1; $i <= 20; $i++) {
$zufall = rand(0,$count);
$result[] = $array[$zufall];
}
return $result;
}
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.
Verfasst: 25.08.2006, 19:29
von net(t)worker
müssteste dann aber jeweils überprüfen ob du ein Element nicht zufällig 2 mal geholt hast
Code: Alles auswählen
function whileschleife($array) {
$count = count($array);
$count = $count-1;
$result = array();
$result2=array();
$i=0;
while ($i < 20) {
$zufall = rand(0,$count);
if (!in_array($zufall,$result2)
{
$result[] = $array[$zufall];
$result2[] = $zufall;
$i++;
}
}
return $result;
}
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($array) {
global $$array;
....
....
$result[] = $$array[$zufall];
....
....
und dann einfach so aufrufen:
Code: Alles auswählen
$grosses_Array = array('a','b',.........);
$zufall_array= whileschleife('grosses_array');
Was sind wir für Freaks...
Verfasst: 25.08.2006, 20:38
von Southmedia
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($array) {
$count = count($array);
$count = $count-1;
$result = array();
$result2 = array();
$i=0;
while ($i < 20) {
$zufall = rand(0,$count);
if (!in_array($zufall,$result2)) {
$result[] = $array[$zufall];
$result2[] = $zufall;
$i++;
}
}
return $result;
}
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?