2016-07-30 38 views
6

Yeni bir dil öğrenmeyi düşündüğüm zaman - bu durumda haskell - dil uygulamasının ve/veya kütüphanelerinin metin işlemede ne kadar iyi olduğunu görmek için ilkel bir grep klonunu bir araya getirmeye çalışıyorum, çünkü bu büyük bir kullanım durumudur. ben mi. code on the haskell wiki esinlenerekİlkel ama etkili grep klonu haskell?

, şu naif girişimi ile geldi: Bu benim bunu istediğini yapıyor gibi görünmektedir

{-# LANGUAGE FlexibleContexts, ExistentialQuantification #-} 

import Text.Regex.PCRE 
import System.Environment 

io :: ([String] -> [String]) -> IO() 
io f = interact (unlines . f . lines) 

regexBool :: forall r l . 
    (RegexMaker Regex CompOption ExecOption r, 
    RegexLike Regex l) => 
    r -> l -> Bool 
regexBool r l = l =~ r :: Bool 

grep :: forall r l . 
    (RegexMaker Regex CompOption ExecOption r, RegexLike Regex l) => 
    r -> [l] -> [l] 
grep r = filter (regexBool r) 

main :: IO() 
main = do 
    argv <- getArgs 
    io $ grep $ argv !! 0 

, ama ne yazık ki, yavaş gerçektenvar - yaklaşık 10 kat daha yavaş Aynı şeyi yapan bir python betiği. Burada hatalı olan regex kütüphanesi olmadığını düşünüyorum, çünkü PCRE'yi çağırmak çok hızlı olmalı (Text.Regex.Posix'a geçmek biraz daha ileride yavaşlar). Yani teorik bir bakış açısından öğretici olan ama okuduğum şeye göre yetersiz olan String uygulaması olmalıdır.

verimli ve uygun ikisi de Haskell String s alternatif var mı (örneğin var çok az veya hiç sürtünme yerine o String s kullanarak geçiş) ve bu tam ve doğru olarak, hem de UTF-8 kodlanmış Unicode kolları mümkünse çok fazla güçlük çekmeden diğer kodlamalar gibi mi? Haskellede metin işlerken herkesin kullandığı, ancak henüz bilmediğim bir şey var, çünkü ben yeni başlayan biriyim?

+7

[Metin] (https://hackage.haskell.org/package/text-1.2.2.1/docs/Data-Text.html) – ErikR

+2

kullanın Yalnızca C-tipi hızların elde edilmesinin mümkün olduğunu belirtmek istedim, ancak biraz çaba gerektirebilir. __cgrep__ - http://awgn.github.io/cgrep/ – ErikR

+4

'String', temel kısa dizeler için" ince "olan, ancak ciddi metin manipülasyonları için uygun olmayan düşük performanslı, tembel bir dizedir. 'Metin ', Unicode metin manipülasyonu için yüksek performanslı bir türüdür. (Ayrıca, metin için ama byte dizileri için _not_ olan ByteString' vardır.) – chi

cevap

1

Yavaş hızın standart kitaplığın liste türünün kullanılması nedeniyle oluşması mümkündür. Geçmişte sık sık performans sorunları yaşadım.

Yürütücünüzü, zamanını nerede geçirdiğini görmek için izlemek iyi bir fikir olabilir: Tools for analyzing performance of a Haskell program. Profilleme Haskell programları gerçekten kolaydır (bir anahtarla derleyin ve programınızı ek bir argümanla çalıştırın ve rapor mevcut çalışma dizinindeki bir metin dosyasına yazılır).

Bir yan not olarak, yeni bir dil öğrenirken tam olarak aynı yaklaşımı kullanıyorum: çalışan bir şey oluşturun. Tecrübelerimi Haskell ile yapmak, profilleme ve göreceli olarak basit değişiklikler yaparak (genellikle birkaç satır) kolayca büyüklük veya ikiye varan bir düzen elde edebilmem.

+0

İpucu için teşekkürler Haskell'in kutudan böyle güzel bir profil desteğini aldığını bilmiyordum! 'Io' ve 'regexBool' daki üçte bir zamanın yaklaşık üçte birini harcadığımı görüyorum (yukarıya bakın), bu yüzden burada gerçek sürpriz yok - Sadece bu aramaları daha hızlı yapmalıyım ... Yukarıdaki diğer yorumcular tarafından işaret edildiği gibi 'String' yerine' Text' kullanılarak yapılabilmesi gereken tek sorun şu ki, programımı henüz başaramadım. Şimdiye kadar bu değişiklik ile typecheck. – dlukes

+0

@dlukes - kullandığınız regex kitaplığına bağlı olarak - regex-heavy'ın 'Text' destekli olduğunu düşünürken diğerleri' String '/ 'ByteString' gibi görünür ancak belki de bu satır içi ile ihtiyaçlarınız için yeterlidir. – epsilonhalbe