Ich verwende derzeit md5_file()
, um ungefähr 15 URLs zu durchlaufen und ihre MD5-Hashes zu verifizieren. Gibt es eine Möglichkeit, dass ich das schneller machen kann? Es dauert viel zu lange, um alle zu durchlaufen.Eine Möglichkeit, md5_file() schneller zu machen?
Antwort
Wahrscheinlich machst du es sequentiell gerade jetzt. I.e. Daten holen 1, Daten verarbeiten1, Daten 2 holen, Daten 2 verarbeiten, ... und der Flaschenhals könnte die Datenübertragung sein.
Sie könnten curl_multi_exec() verwenden, um das ein wenig zu parallelisieren. Entweder ein CURLOPT_WRITEFUNCTION registrieren und jeden Datenblock verarbeiten (schwierig, da md5() genau einen Datenblock verarbeitet).
Oder prüfen Sie, ob Curl-Handles bereits fertig sind, und verarbeiten Sie dann die Daten dieses Handles.
bearbeiten: quick & schmutzig Beispiel mit den hash extension (welchen Funktionen für inkrementellen Hashes bereitstellt) und ein php5.3+ closure:
$urls = array(
'http://stackoverflow.com/',
'http://sstatic.net/so/img/logo.png',
'http://www.gravatar.com/avatar/212151980ba7123c314251b185608b1d?s=128&d=identicon&r=PG',
'http://de.php.net/images/php.gif'
);
$data = array();
$fnWrite = function($ch, $chunk) use(&$data) {
foreach($data as $d) {
if ($ch===$d['curlrc']) {
hash_update($d['hashrc'], $chunk);
}
}
};
$mh = curl_multi_init();
foreach($urls as $u) {
$current = curl_init();
curl_setopt($current, CURLOPT_URL, $u);
curl_setopt($current, CURLOPT_RETURNTRANSFER, 0);
curl_setopt($current, CURLOPT_HEADER, 0);
curl_setopt($current, CURLOPT_WRITEFUNCTION, $fnWrite);
curl_multi_add_handle($mh, $current);
$hash = hash_init('md5');
$data[] = array('url'=>$u, 'curlrc'=>$current, 'hashrc'=>$hash);
}
$active = null;
//execute the handles
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
while ($active && $mrc == CURLM_OK) {
if (curl_multi_select($mh) != -1) {
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
}
foreach($data as $d) {
curl_multi_remove_handle($mh, $d['curlrc']);
echo $d['url'], ': ', hash_final($d['hashrc'], false), "\n";
}
curl_multi_close($mh);
(nicht die Ergebnisse, obwohl überprüft ... es ist nur ein Ausgangspunkt)
+1. Parallelisierung von Downloads ist wahrscheinlich ein großer Gewinn hier. Du könntest auch den md5-Teil parallelisieren, entweder mit dem 'md5sum' CLI-Befehl (zB' exec ('bash -c "md5sum file1> file1.md5 &' ')'), oder mit etwas wie PHP's pcntl_fork() mehrere Aufrufe an md5_sum() abzweigen. Diese beiden haben ihre Nachteile, aber im richtigen Kontext sind sie vielleicht das Beste. –
Und ich muss zugeben, dass ich nicht einmal getestet habe, ob der Download wirklich fortgesetzt wird, während der Callback ausgeführt wird. Aber da die Datenanteile angeblich klein sind, hoffe ich, dass es (viel) keine Rolle spielt. – VolkerK
Der MD5-Algorithmus ist so schnell wie es geht, und das Abrufen von URLs ist so schnell wie es nur geht (langsam, wenn die Dateien riesig sind oder Sie eine langsame Verbindung haben). Also nein. Du kannst es nicht schneller machen.
Nun offensichtlich kann man nicht mit md5_file()
alles tun, schneller zu machen, können Sie jedoch einige micro-optimizations oder Code Refactoring verwenden, um einige Geschwindigkeitsgewinn zu erhalten, aber wieder können Sie die eingebaute Funktion md5_file()
beschleunigen.
... Sicher, ein paar Micro-Optimierungen könnten 2 Millisekunden seiner Laufzeit rasieren. Könnte sein. Oder er könnte einfach die URLs parallel ziehen und ein paar Sekunden sparen. "Mikrooptimierungen" sind fast nie die Mühe wert. –
@Frank, Dies wurde vor der Frage veröffentlicht, die bearbeitet wird, um den fraglichen Code tatsächlich einzuschließen (der, bis Code hinzugefügt wurde, im Grunde gefragt wurde, wie man md5_file() beschleunigt). –
Nein. Da dies eine eingebaute Funktion ist, gibt es keine Möglichkeit, es schneller zu machen.
Wenn Ihr Code jedoch Dateien herunterlädt, bevor diese heruntergeladen werden, kann es möglich sein, Ihre Downloads schneller zu optimieren. Sie können auch eine kleine Geschwindigkeitssteigerung feststellen, indem Sie die Größe der Datei (mit ftruncate) vor dem Schreiben einstellen, wenn Sie die Größe im Voraus kennen.
Wenn die Dateien klein genug sind, um im Speicher zu bleiben, und Sie sie bereits im Speicher haben (weil sie heruntergeladen wurden oder für einen anderen Zweck gelesen werden), können Sie verwenden anstelle von md5_file
, die es erfordert, dass es erneut von der Festplatte gelesen werden.
Vermutlich werden dieselben URLs über einen bestimmten Zeitraum hinweg überprüft? Können Sie die zuletzt geänderten Header für die URL überprüfen? Wenn sich die zu überprüfende Seite nicht geändert hat, ist eine Neuberechnung des MD5 nicht erforderlich.
Sie könnten die Seiten auch asynchron anfordern, damit sie parallel und nicht seriell verarbeitet werden können, was die Geschwindigkeit erhöhen sollte.
Die Geschwindigkeit des MD5-Algorithmus ist linear. Je größer die Eingabe ist, desto mehr Zeit wird benötigt. Wenn also die Datei groß ist, können Sie nicht viel tun.
Jetzt, wie VolkerK bereits vorgeschlagen, das Problem ist höchstwahrscheinlich nicht das md5 Hashing sondern das Abrufen und Lesen der Datei über das Netz.
Ich sehe einen sehr guten Vorschlag zur Optimierung here. Dies funktioniert besonders gut für große Dateien, wo md5_file die Datei liest und diese Funktion nur das zweite Byte jeder Datei vergleicht.
Erklären, was Sie tun möchten, würde helfen. Wenn Sie eine Datei mit ihren MD5-Hashes verifizieren möchten:
Es ist keine sichere Methode, da es anfällig für Collision attack ist. Sie sollten mehrere Hashes verwenden (z. B. indem Sie die Datei aufteilen) oder andere Hash-Methoden verwenden.
- 1. es muss eine Möglichkeit geben, dieses PHP schneller zu machen
- 2. Gibt es eine Möglichkeit, mein Wortzählprogramm schneller zu machen, ohne unreine Tricks zu verwenden?
- 3. Gibt es eine Möglichkeit, Schleifen zu vermeiden, um diesen Code schneller zu machen?
- 4. Zuverlässige Möglichkeit, eine ACTION_IMAGE_CAPTURE Absicht zu machen?
- 5. Gibt es eine Möglichkeit, dies schneller zu machen? MemoryStream vs FileStream
- 6. Gibt es eine effiziente Möglichkeit, die Abfrage von Android-Datenbanken schneller zu machen?
- 7. Es ist möglich, SpeechRecognizer schneller zu machen?
- 8. Eine Histogrammberechnung in Haskell schneller machen
- 9. Machen kumulative Summe schneller
- 10. Java irgendwelche Möglichkeiten, Wurzel schneller zu machen?
- 11. Gibt es eine Möglichkeit, eine lokale Niederlassung unveränderlich zu machen?
- 12. Kann regex das schneller machen?
- 13. Gibt es eine Möglichkeit, die C# -Bindung statisch zu machen?
- 14. Gibt es eine Möglichkeit, jQuery.inArray() case-insensitiv zu machen?
- 15. Gibt es eine Möglichkeit, Rails ActiveRecord Attribute privat zu machen?
- 16. gibt es eine Möglichkeit, diesen Code kürzer zu machen?
- 17. Gibt es eine Möglichkeit, jQuery-Ausgabe * tatsächliches Markup * zu machen?
- 18. Gibt es eine Möglichkeit, Sellerie/RabbitMQ persistent zu machen?
- 19. Gibt es eine Möglichkeit, SIFR-Schriftart als Schriftart zu machen?
- 20. Gibt es eine Möglichkeit, den `enum` -Typ vorzeichenlos zu machen?
- 21. Gibt es eine Möglichkeit, TFS linkbar zu machen?
- 22. Gibt es eine Möglichkeit in C curry zu machen?
- 23. Gibt es eine bessere Möglichkeit, diesen Python-Code zu machen?
- 24. Gibt es eine Möglichkeit, ein zugängliches Modal zu machen?
- 25. Gibt es eine Möglichkeit, ein UserControl unkenntlich zu machen?
- 26. Gibt es eine Möglichkeit, dieses JQuery-Karussell effizienter zu machen?
- 27. Schnellste Möglichkeit, eine ungeprüfte ganzzahlige Addition in VB.Net zu machen?
- 28. Gibt es eine Möglichkeit, JNLP ohne Zertifikate zu machen?
- 29. Gibt es eine Möglichkeit, den iPad-Simulator größer zu machen?
- 30. Gibt es eine Möglichkeit, ein HTML-Element schlank zu machen?
"ungefähr 15 URLs durchlaufen" bedeutet etwas wie 'md5_file ('http: //some.url/foo')' in einer Schleife mit 15 verschiedenen URLs? Wie groß sind diese "Dateien"? – VolkerK
Ja, genau das ist es. Ich ziehe sie aus einer MySQL-Datenbank und führe sie dann in md5_file ($ result) in einer Schleife aus. Die Dateien sind sehr klein und haben tatsächlich keine Bildschirmausgabe, keine Benutzeroberfläche, nur eine leere weiße Seite beim Betrachten. – Rob
Das Problem ist, dass Sie die Hashes nacheinander und nicht parallel berechnen; 'md5_file' ist nicht der Flaschenhals. Auch wird der Hash einer leeren Datei immer gleich sein. – salathe