bir preg_match'in bir işlevi daha) daha hızlı sıralı strpos (?

3 Cevap php

i test etmek gerekir dizeleri herhangi bir 'merhaba', 'ben ben' varsa, 'aptal' $ ohreally, if even one of them exists my test is over, and i have the knowledge that neither of the others will occur if one of them has. denilen uzun dize var

Bu koşullar altında ben bu arama yazmak için en verimli yolda yardım için soruyorum,

strpos () böyle 3 kez?

if (strpos ($ohreally, 'hello')){return false;}  
   else if (strpos ($ohreally, 'i am')){return false;}  
   else if (strpos ($ohreally, 'dumb')){return false;}  
   else {return true;}

ya da bir preg_match?

if (preg_match('hello'||'i am'||'dumb', $ohreally)) {return false}   
   else {return true};

Ben preg_match kodu yanlış olduğunu biliyorum kimse bunun doğru sürümünü sunmak mümkün olsaydı, ben gerçekten takdir ediyorum.

Thank You!


Answer

Cletus söylediklerini okudum ve deney middaparka feryat yaptım lütfen. Ben de uzun ve kısa çeşitli dizeleri bir mirco zaman testi yaptım. Bu sonuçlar ile

Eğer en azından en muhtemel dan SİPARİŞ onları oluşan dize değerlerinin olasılığını bilmek, IF. (I /hello|i am|dumb/ veya /i am|dumb|hello/ arasındaki, yani regex kendisi sipariş bir prezentabl farklı fark etmedi.

Diğer taraftan ardışık olarak strpos olasılığı tüm fark. Örneğin 'merhaba' eğer 'ben varım'% 7 ve zamanın 'aptal' yüzde 3,% 90 olur. Önce 'merhaba' kontrol ve kısa sürede işlevini çıkmak için kodunuzu düzenlemek istiyoruz.

Benim microtime testleri bu gösteriyor.

iğne ve birinci, ikinci ve üçüncü strpos () uygulama sırasıyla bulunan edildiği haystacks A, B ve C için, zaman aşağıdaki gibidir,

strpos:
A: 0.00450 seconds // 1 strpos()
B: 0.00911 seconds // 2 strpos()
C: 0.00833 seconds // 3 strpos()
C: 0.01180 seconds // 4 strpos() added one extra

and for preg_match:
A: 0.01919 seconds // 1 preg_match()
B: 0.02252 seconds // 1 preg_match()
C: 0.01060 seconds // 1 preg_match()

sayılar gösterdiği gibi, strpos hızlı 4rth yürütülmesi kadar, bu yüzden ben kontrol etmek için sadece 3, alt-sokmaları beri i yerine onu kullanıyor olacak:)

3 Cevap

Doğru sözdizimi:

preg_match('/hello|i am|dumb/', $ohreally);

Ben de yol çok içinde orada şüpheliyim ama strpos() yöntemi aradığınız dizeleri sayısına bağlı olarak daha hızlı olursa bana sürpriz olmaz. Performans strpos() arama terimleri artar sayısı olarak düşer. Regex muhtemelen ama değil gibi hızlı olacaktır.

Açıkçası düzenli ifadeler daha güçlüdür. Eğer "aptal", "aptal" değil, kelime maç istedim Örneğin o kolay ile yapılır:

preg_match('/\b(hello|i am|dumb)\b/', $ohreally);

Hangi strpos() ile yapmak çok daha zor.

Note: teknik \b sıfır genişlikli kelime sınırıdır. "Sıfır-width" it sınır o dizenin sonunda, kelimenin (rakam, harf veya alt çizgi) bir geçiş karakterleri olmayan dize başlangıcını eşleşen anlamına giriş dizesi ve sözcüğün herhangi bir bölümünü tüketmek anlamına gelir sözcük karakter veya olmayan kelime kelime karakter bir geçiş. Çok faydalı.

Edit: o incorrect de sizin kullanım strpos() olduğunu bilmenizde yarar var (ama bir sürü insan aynı hatayı yapmak). Yani:

if (strpos ($ohreally, 'hello')) {
  ...
}

iğne dize 0 konumunda ise durum blok girmek olmaz. Doğru kullanım şöyledir:

if (strpos ($ohreally, 'hello') !== false) {
  ...
}

tipi hokkabazlık çünkü. Aksi halde 0 false dönüştürülür.

Çılgın bir fikir, ama neden sınamak değil hem 'n' iki ayrı döngüler, hem microtime () çevrili bin kat; ve ilişkili hata ayıklama çıktı.

1,000 tekrarlamalar için (birkaç düzeltmeleri ile) Yukarıdaki kod dayanarak, ben gibi bir şey olsun:

strpos test:     0.003315
preg_match test: 0.014241

Gibi, bu durumda (başkaları tarafından özetlenen sınırlamalar) strpos gerçekten hızlı görünüyor, albeit by a largely meaningless amount. (Anlamsız mikro-optimizasyon sevinç, vb)

Never estimate what you can measure.

Bu aramak istediğiniz dizeleri sayısı ve aradığınız dize uzunluğuna bağlıdır.

Sen doğru olduğunu öğrenmek için belirlenen bir temsilci verileri ile deneme gerekiyveyadu (işlemi tekrarlayın 1000 kez söylemek ve zaman gecikmesini ölçmek).

'(Aptal | | öyleyim merhaba') - BTW arıyveyasun regex olduğunu düşünüyveyaum

Ayrıca, kod olması gerekiyveya daha ayrıntılı olduğunu:

return strpos($ohreally, 'hello') || strpos($ohreally, 'i am') || strpos($ohreally, 'dumb');

veya

return preg_match('(hello|i am|dumb)',$ohreally);

Ayrıca, her zamanki kodlama standartlarına göre, işlev adı ve dirsek arasında boşluk olmamalıdır.

C.