Simplexml_load_file (ne kadar hızlı?)

7 Cevap php

Benim Mashup'a için last.fm 'in API ile kullanıcı verileri çok getiriliyor ediyorum. Ben dinleme veri toplamak zorunda gibi ben her hafta bunu.

Ben onların REST API ve XML üzerinden veri alıp: daha spesifik simplexml_load_file().

Komut gülünç uzun sürüyor. Yaklaşık 2 300 kullanıcıları için, komut sanatçıların sadece adlarını almak için 30 dakika sürer. Ben başka türlü benim hosting şirketi beni kapanacak, şimdi bunu düzeltmek zorundayız. Ben senaryoyu yavaşlıyor XML, diğer tüm seçenekler siphoned ettik.

Ben şimdi last.fm yavaş API (veya onları bize söylemeden aramaları sınırlayan), ya da PHP'nin SimpleXML aslında oldukça yavaş olup olmadığını anlamaya var.

Anladım bir şey XML isteği ihtiyacım daha çok getirir, ama ben (yani 70, bana sadece 3 bantlarında bilgi vermek değil) API aracılığıyla sınırlamak değil ki. Ama "büyük" XML dosyaları sadece 20kb olsun. Bundan olabilir, bu senaryoyu yavaşlıyor? 2300 kullanıcıların her biri için bir nesne haline 20KB yüklemek zorunda?

Bu olabilir mantıklı değil ... Ben sadece muhtemelen last.fm 'in yavaş API olduğunu teyit etmesi gerekiyor. Yoksa değil mi?

Eğer sağlayabilir diğer herhangi bir yardım?

7 Cevap

Ben basit xml bir ayrıştırıcı çünkü yavaş, yavaş olduğunu sanmıyorum ama ben 2300 kıvırmak / file_get_contents çok daha fazla zaman alıyor düşünüyorum. Ayrıca neden veriyi bulup yok ve sadece simplexml_load_string kullanmak, gerçekten sunucunun diskinizdeki bu dosyayı koymak gerekiyor?

Bellekten en az yükleme ayrıca yüklenen XMLs üzerinde işlem ne tür gidiyorsun, bir şeyler biraz hızlandırmak gerekir? Eğer bu olabilir gibi işleme verimli olduğuna emin misin?

20kb * 2300 kullanıcıların ~ 45MB. Eğer ~ 25kB/sec indirilmesi ediyorsanız, sadece verileri indirmek için 30 dakika sürer, dursun ayrıştırmak olacaktır.

Eğer last.fm indirdiğiniz XML gzip'li emin olun. Muhtemelen gzip destek sunucusu anlatmak için doğru HTTP başlığını eklemek gerekiyor. Bu indirme hızlandırmak ama ungzipping kısmı ile daha fazla sunucu kaynaklarını yemek istiyorum.

Ayrıca sunucu kaynaklarını boşaltmak için uyumsuz siteleri kullanarak düşünün. Bu mutlaka sürecini hızlandırmak değil, ancak sunucu yöneticileri mutlu etmeli.

XML kendisi büyük ise, bunun yerine bir DOM çözümleyici, bir SAX çözümleyici kullanabilirsiniz.

Ben saniyede 1 API çağrısı bir sınırı olduğunu düşünüyorum. Bu politika kodu ile zorlanan ediliyor emin değilim, ama onunla bir ilgisi olabilir. Bu durum olduğuna inanıyorum eğer irc.last.fm # AudioScrobbler de IRC Last.fm personel sorabilirsiniz.

Ne gerçekten yapmak gerektiğini uygulamanızı profil etmektir. Profilleme kodunuzu hangi parçası böylece, çalıştırmak için en çok zaman alan tüm belleği iliklerine ve size söyleyecektir.

PHP'nin xdebug Bunun için kullanabileceğiniz bir profiler var.

Ben tür herhangi bir kullanıcı 50 ünlü sanatçı şarkı isimlerini ve playcounts getirmek için çalışılıyor .. benzer bir sorun yaşıyorum ... bir süre sonra çok yavaş olduğunu öğrendim. Örneğin - Eğer sadece şarkı isimleri ve sanatçı playcounts istiyorum, ve 50 şarkı varsa - bu, size şarkı isimleri ve playcounts sadece diğer tüm meta göndereceğiz. 50 şarkı meta ile bir XML 40KiB hakkında ... yani evet o (= yavaş

Önerildiği gibi, veri almaya ve simplexml_load_string ziyade dayanarak simplexml_load_file kullanarak ayrıştırmak - yaklaşık iki kat daha hızlı çalışır. İşte bazı kod:

function simplexml_load_file2($url, $timeout = 30) {


// parse domain etc from url
$url_parts = parse_url($url);
if(!$url_parts || !array_key_exists('host', $url_parts)) return false;

$fp = fsockopen($url_parts['host'], 80, $errno, $errstr, $timeout);
if($fp) 
{
    $path = array_key_exists('path', $url_parts) ? $url_parts['path'] : '/'; 
    if(array_key_exists('query', $url_parts)) 
    {
        $path .= '?' . $url_parts['query'];
    }

    // make request
    $out = "GET $path HTTP/1.1\r\n";
    $out .= "Host: " . $url_parts['host'] . "\r\n";
    $out .= "Connection: Close\r\n\r\n";

    fwrite($fp, $out);

    // get response
    $resp = "";
    while (!feof($fp))
    {
        $resp .= fgets($fp, 128);
    }
    fclose($fp);

    $parts = explode("\r\n\r\n", $resp);
    $headers = array_shift($parts);

    $status_regex = "/HTTP\/1\.\d\s(\d+)/";
    if(preg_match($status_regex, $headers, $matches) && $matches[1] == 200)
    {
        $xml = join("\r\n\r\n", $parts);    
        return @simplexml_load_string($xml);            
    }   

}
return false; }