2010-04-27 18 views
8

Bir derste kullandığımız bazı dosya biçimleri (ARFF) için elle tekrarlanan salt bir python ayrıştırıcısı yazdım. Şimdi alıştırma sunumumu yürütmek çok yavaş. Çok fazla zaman ayrıştırıcımda harcanıyor. Çok fazla CPU zamanı tüketiyor, HD darboğaz değil.python'da hızlı bir ayrıştırıcı yazma

Python'da ayrıştırıcı yazmak için hangi performans yollarının olduğunu merak ediyorum. Onu tekrar yazmamayı tercih ederim. Jython'u kullanmaya çalıştım ama bu performansı çok düşürdü! Ayrıştırdığım dosyalar çok uzun satırlarla kısmen devasa (> 150 MB).

Şu anki ayrıştırıcımın yalnızca bir karakterden ileriye bakması gerekiyor. Kaynağı buraya gönderiyorum ama bunun iyi bir fikir olup olmadığını bilmiyorum. Son başvuru tarihinden sonra henüz bitmedi. Fakat sonra, bu alıştırmadaki odak ayrıştırıcı değildir. Kullanmak istediğiniz dili seçebilir ve zaten Java için bir ayrıştırıcı var.

Not: Ben bir x86_64 sistemi çok psyco (ve aynı zamanda PyPy gibi görünüyor) bir seçenek yok.

Güncelleme: Şimdi çözümleyicimi/yazıcımı bitbucket'a yükledim.

+4

Ayrıştırıcınızı geliştirdiniz mi? Şanslar, herşeyi tutan tek bir darboğaz. –

+0

Bir kod örneği olmadan, iyi bir tavsiye vermek imkansızdır. Bir büyük kusurlu bir ses tekniği kullanıyor olabilirsiniz ya da tüm yaklaşımınızın yeniden işlenmesi gerekebilir, bilmemizin bir yolu yoktur. – mikerobi

+0

Onunla psyco kullanmayı denediniz mi? –

cevap

8

ANTLR veya pyparsing'u kullanabilirsiniz, ayrıştırma işleminizi hızlandırabilirler.

Ve eğer mevcut kodunuzu korumak istiyorsanız,/PyPy'a bakmak isteyebilirsiniz, bu sizin perfomance (bazen 4x'e kadar) artırır.

+1

Püskürtme işleminin işleri hızlandıracağı olası değildir, ancak darboğazların nerede olduğu konusunda biraz bilgi verebilir. Ayrıca, bir ARFF pyparsing ayrıştırıcısının zaten yazıldığı ve bir yerde eterin içinde olduğuna inanıyorum. – PaulMcG

+0

Bu doğru - ve Pypy veya Cython ile uyuşmanın nasıl olduğunu bilmiyorum. – wvd

+0

weka sitesinden bağlanan ARFF pyparsing ayrıştırıcısı son derece eksik (eğer bahsettiğiniz buysa). Aynı zamanda cython'u denedim, ama çok fazla verim kullandığım için bir hg sürümü kullanmam gerekti, bu da tüm yaptıkları kod parçalarını üretiyor. – panzi

7

Daha fazla bilgi vermeden vereceğim en genel ipucu, tüm dosyayı veya en azından önemli bir bölümünü bir kerede belleğe okumak olacaktır. Her seferinde bir karakteri okumak ve burada ve orada aramak istemezsiniz; Kaputun altında devam eden tamponlamadan bağımsız olarak, bellekte her şeyi elde etmek iyi bir fikir olabilir, ancak istediğinizde çalışabilirsiniz.

Python'da ayrıştırıcılar yazdım ve özellikle başka bir dilde yazılmış bir ayrıştırıcıdan daha yavaş olmaları için özel bir gereksinim yok. Bu tür şeylerle olduğu gibi, yapmanız gerekmediği için iş yaptığınız daha olasıdır. Bu sınıf sınıfından, aynı nesnenin yaratılması ve yok edilmesi ve yeniden yaratılması, sadece bir yere saklamaktan daha maliyetlidir. Bir değeri tekrar tekrar hesaplamak, bir yere saklamaktan daha maliyetlidir. Vb. Vb.

Python'da, insanların içine düştüğü bir tuzak, gereksiz bir çok dize manipülasyonu yapmaktır. Dizeleri bir seferde bir karaktere eklemeyin; Jetonlarınızı oluştururken "master" dizginiz üzerinde çalışın ve bir tokmak içinde belirteci dışarı şerit. (Diğer bir deyişle, "ana" dizgisi dizinine indeksleyin, başlangıç ​​ve bitiş noktalarını belirleyin ve token = master[start:end] ile yakalayın.) Dizgecik birleştirme yapmak, her seferinde performans sefaletine giden kısa bir yoldur. Eğer bir nedene ihtiyacım var/for c in master: newstr += c yapmak için bile 'c' bir liste içine doldurma ve newstr = ''.join(newstr_charlist) daha iyi şanslar olabilir şüpheleniyorum.

+0

Bunun gibi şeyleri çok kullanıyorum, bu en hızlı yol mu? Ancak, bu özel kod, benim durumları kullanmam tarafından tetiklenmez. http://pastebin.com/yAmEcKB8 – panzi

+0

Oh ve ben dosyadan 4096 baytlık parça okudum (readc() ve peek() yöntemi bu parçalar üzerinde çalışır). Dosyaların 150 MB büyüklüğünde olması nedeniyle delik dosyasını okumak iyi bir fikir olmaz. – panzi

+2

Modern bilgisayarlarda 512M veya daha fazla bellek var. 150MB okuma hiçbir şey değildir. :) –