2009-03-11 20 views
18

Bir dizeyi ayrıştırmak için PHP kodunu yazıyorum. Olabildiğince hızlı olmalı, düzenli ifadeler de gidilecek mi? PHP string fonksiyonlarının daha pahalı olmasının bir önsezi var, ama sadece bir tahmin. Gerçek nedir? şey atmadan,PHP'de daha verimli, PHP string işlevleri veya regex hangisi?

tut (bir alt dize "000000" üçüncü yere göre) ilk yarısı ve sonraki 20 bayt olan karma karşılaştırmak sol: Burada

Ben dize ile yapmanız gerekenler özellikle bulunuyor .

9. baytı bir sonraki "000000" ile tek bir veri parçası olarak ayrıştırın. Ardından, sonraki 19 baytı yakalayın ve bunu 8'e (1'e at) ve 8'e bölün. Sonra bu iki 8 baytlık dizeyi tarihlere dönüştüren başka şeyler yapıyorum.

Bu yüzden yapmam gereken bir şey var.

cevap

16

Durumunuza bağlıdır: eğer oldukça basit bir şey yapmaya çalışıyorsanız (örneğin: bir dizeyi aramak, bir alt dizeyi başka bir şeyle değiştirmek), daha sonra normal dize işlevleri gitmenin yoludur. Daha karmaşık bir şey yapmak istiyorsanız (örneğin: IP adreslerini aramak için), Regex işlevleri kesinlikle daha iyi bir seçimdir.

Düzenli ifadeler oluşturmadım, bu nedenle çalışma süresinde daha hızlı olacaklarını söyleyemem, ancak temel işlevleri kullanarak eşdeğer bir hatayı bir araya getirerek harcayacağınız zamanın buna değmeyeceğini söyleyebilirim. OP yeni bilgilerle


Düzenleme:

O gerçekten burada küçük dize alan bir dizi operasyon yapmak gerekir sanki duyulur. Her biri ayrı ayrı oldukça temel ve ben bir düzenli ifade ile bir kez tüm bu adımları (hatta bu adımları bir çift) yapmak mümkün olacağını şüpheliyim, temel işlevleri ile gitmek istiyorum:

İlk yarımı ("000000" alt dizesinin üçüncü konumuna göre) yakalayın ve hash değerini bir sonraki 20 bayta karşılaştırın, kalan her şeyi atın.

kullanımı: strpos() ve substr()
veya: /$(.*?0{6}.*?0{6}.*?)0{6}/

Sonra bu sonraki 19 bayt kapmak ve bölme 8 içine (atmak 1) ve 8

kullanım olup : substr() - (Burada 17 bayt kastettiğinizi varsayıyorum - 8 + 1 + 8)

$part1 = substr($myStr, $currPos, 8); 
$part2 = substr($myStr, $currPos + 9, 8); 
+1

Normal İfade şaşırtıcı olan Ben sadece bir kanıtı olarak terminalde yaptığını, küçük bir test göstermek istedim verimli. Genelde bunları varsayılan araç olarak kullanmaktan korkmamalısınız. – troelskn

+1

@troelskn, ancak, php's belgelerinde genellikle normal çalışmaların çoğu için normal php fonksiyonundan daha yavaş olduklarını ifade ederler, çünkü regex motorunu kullanmayanlar. – T0xicCode

1

Yerel dize işlevleri çok daha hızlı. Regexp'in yararı, onlarla hemen hemen her şeyi yapabileceğinizdir.

6

Normal bir ifadenin bir dizi PHP dize işlev çağrısından daha hızlı olduğu bir eşiğin olduğuna inanıyorum. Her neyse, yaptığınız şeye çok bağlı. Dengeyi bulmalısın.

Sorunuzu düzenlediğinize göre. Başarmaya çalıştığınız şey için dize işlevlerini kullanırdım. strpos() ve substr() ilk bakışta akla gelen şeydir.

6

En yüksek performansı istiyorsanız, çabayı en aza indirmeye yardımcı olduğu için düzenli ifadelerden kaçınmalısınız, ancak en iyi performansa sahip olamayacağınızdan, kod dizisini belirli bir soruna neredeyse her zaman ayarlayabilir ve büyük bir performans kazanabilirsiniz Bunun artırılması. Ancak, çok fazla optimize edilemeyen basit ayrıştırma rutinleri için, hala orada büyük bir fark yaratmayacağı için normal ifadeyi kullanabilirsiniz.

DÜZENLEME: Gönderdiğiniz bu belirli sorun için, dize işlemleri destekledim, ancak yalnızca bunu düzenli olarak nasıl yapılacağını bilmem. Bu, karma hariç, oldukça basit gibi görünüyor, bu yüzden regex/string işlevlerinin büyük bir fark yaratmayacağını düşünüyorum.

0

Gereksinimlerinize bağlıdır. Düzenli ifade işlemlerinin çoğu, düşünceden daha hızlıdır ve belirli önemsiz işlemlerde yerleşik dizge işlevlerinden bile daha iyi performans gösterebilir. Çok yavaş olan yerleşik regex kütüphanesini değil, ön kütüphaneyi göz önünde bulundurduğumu unutmayın.

4

Yaptığınız şey dize işlevlerini kullanmak için makul ise, bunları kullanmalısınız. 'abc' sabit bir dizginin $value içinde gerçekleşip gerçekleşmediğini belirliyorsanız, preg_match('/abc/', $value)'u değil strpos($value, 'abc') !== false'u kesinlikle kontrol etmek istersiniz. Eğer bir regex ile neyi yapabildiğinizi gerçekleştirmek için kendinize çok fazla ipucu değiştirme ve dönüşüm yapıyorsanız, neredeyse hem performans hem de sürekliliği ortadan kaldıracaksınız.

Hız hakkında endişe duysa da, aşağıya indiğinde, bunun hakkında düşünmeyin, saatin. time komutu arkadaşınız.

4

Genel olarak, dize işlevleri daha hızlıdır ve normal işlevler daha esnektir.

Diğer her şeyde olduğu gibi, sonuçlarınız değişebilir, kesin olarak bilmenin tek yolu iki yolu denemek ve karşılaştırmaktır.

2

Herkesle aynı fikirdeyim: string işlevleri regex işlevlerinden biraz daha fazla performans gösterir.

strpos():

$ time php -r '$i = 0; while($i++ < 1000000) strpos("abc", "a");' 

real 0m0.380s 
user 0m0.368s 
sys 0m0.008s 

preg_match():

$ time php -r '$i = 0; while($i++ < 1000000) preg_match("/abc/", "a");' 

real 0m0.441s 
user 0m0.432s 
sys 0m0.004s