Phương pháp nào được ưu tiên strstr hoặc strpos?


84

Tôi nhận thấy rất nhiều nhà phát triển đang sử dụng cả strstr và strpos để kiểm tra sự tồn tại của chuỗi con. Có phải một trong số họ được ưa thích và tại sao?


2
điểm chuẩn bạn đã đề cập là so với substr không phải strstr
Flask

Câu trả lời:


125

Từ hướng dẫn sử dụng PHP trực tuyến :

Nếu bạn chỉ muốn xác định xem một cây kim cụ thể có xuất hiện trong đống cỏ khô hay không, hãy sử dụng chức năng nhanh hơn và ít tốn bộ nhớ hơn strpos() .


13
+1, Bạn có thể sử dụng strpos hoặc stripos. và đừng quên kiểm tra các cảnh báo trên php doc về việc sử dụng === FALSE;
fedmich

7
Để nói rõ hơn về nhận xét của fedmich: Tôi luôn sử dụng if(strpos($haystack,$needle) !== false) { // do something }, không bao giờ if(strpos($haystack,$needle)) { // do bad things }. strpossẽ trả về 0 nếu giá trị $needleở đầu $haystackvà 0 được coi là sai. (0 == false)đánh giá đúng. (0 === false)đánh giá thành false.
Buttle Butkus

1
Những người đến từ C có thể nghĩ đến việc sử dụng hàm strchr , nhưng trong PHP, nó thực sự là một bí danh cho strstr , vì vậy strpos là một lựa chọn tốt hơn.
e2-e4

38

Đây là một số câu trả lời khác (+ điểm chuẩn) mà tôi nhận được cho câu hỏi của mình, câu này cũng gần giống (tôi không nhận ra câu trả lời của bạn khi hỏi).


Trong khi chờ đợi tôi cũng đã thử nghiệm benchmark của riêng tôi, mà tôi chạy 1000000 lần cho mỗi chức năng có liên quan ( strstr(), strpos(), stristr()stripos()).
Đây là mã:

<?php

function getmicrotime() {
    list($usec, $sec) = explode(" ", microtime());
    return ((float) $usec + (float) $sec);
}

$mystring = 'blahblahblah';  
$findme = 'bla';  

echo 'strstr & strpos TEST:<pre>';
$time_start = getmicrotime();
for($i=0; $i<1000000; $i++) strstr($mystring, $findme);
$time_needed_strstr = getmicrotime() - $time_start;
echo 'strstr():            ',
    round( $time_needed_strstr , 8 ). PHP_EOL;

$time_start = getmicrotime();
for($i=0; $i<1000000; $i++) stristr($mystring, $findme);
$time_needed_stristr = getmicrotime() - $time_start;
echo 'stristr():           ',
    round( $time_needed_stristr , 8 ) . PHP_EOL;

$time_start = getmicrotime();
for($i=0; $i<1000000; $i++) strpos($mystring, $findme) !== false;
$time_needed_strpos = getmicrotime() - $time_start;
echo 'strpos() !== false:  ',
    round( $time_needed_strpos , 8 ) . PHP_EOL;

$time_start = getmicrotime();
for($i=0; $i<1000000; $i++) stripos($mystring, $findme) !== false;
$time_needed_stripos = getmicrotime() - $time_start;
echo 'stripos() !== false: ',
    round( $time_needed_stripos , 8 ) . PHP_EOL;

echo PHP_EOL;

echo 'time_needed_stristr - time_needed_strstr: ',
     round( $time_needed_stristr - $time_needed_strstr , 8) . PHP_EOL;
echo 'time_needed_stripos - time_needed_strpos: ',
     round( $time_needed_stripos - $time_needed_strpos , 8) . PHP_EOL;

echo PHP_EOL;

echo 'time_needed_strstr  - time_needed_strpos:  ',
     round( $time_needed_strstr - $time_needed_strpos , 8) . PHP_EOL;
echo 'time_needed_stristr - time_needed_stripos: ',
     round( $time_needed_stristr - $time_needed_stripos , 8) . PHP_EOL;

echo '</pre>';

?>

Và đây là kết quả đầu tiên, cho thấy đó strpos()là người chiến thắng :

strstr & strpos TEST:
strstr():            2.39144707
stristr():           3.65685797
strpos() !== false:  2.39055395
stripos() !== false: 3.54681897

time_needed_stristr - time_needed_strstr: 1.2654109
time_needed_stripos - time_needed_strpos: 1.15626502

time_needed_strstr  - time_needed_strpos:  0.00089312
time_needed_stristr - time_needed_stripos: 0.110039 

Kết quả tiếp theo tương tự với kết quả đầu tiên (lại strpos()là người chiến thắng):

strstr & strpos TEST:
strstr():            2.39969015
stristr():           3.60772395
strpos() !== false:  2.38610101
stripos() !== false: 3.34951186

time_needed_stristr - time_needed_strstr: 1.2080338
time_needed_stripos - time_needed_strpos: 0.96341085

time_needed_strstr  - time_needed_strpos:  0.01358914
time_needed_stristr - time_needed_stripos: 0.25821209

Dưới đây là một cái khác, thú vị hơn, vì trong trường hợp này, strstr()là người chiến thắng:

strstr & strpos TEST:
strstr():            2.35499191
stristr():           3.60589004
strpos() !== false:  2.37646604
stripos() !== false: 3.51773095

time_needed_stristr - time_needed_strstr: 1.25089812
time_needed_stripos - time_needed_strpos: 1.14126492

time_needed_strstr  - time_needed_strpos:  -0.02147412
time_needed_stristr - time_needed_stripos: 0.08815908

Điều này có nghĩa là nó thực sự có thể phụ thuộc vào "hoàn cảnh môi trường" , đôi khi khó ảnh hưởng và có thể thay đổi kết quả của "nhiệm vụ tối ưu hóa vi mô" như thế này, trong trường hợp bạn chỉ đang kiểm tra xem một chuỗi có tồn tại trong một chuỗi khác hay không.

NHƯNG tôi nghĩ trong hầu hết các trường hợp, strpos()là người chiến thắng so với strstr().

Tôi hy vọng bài kiểm tra này hữu ích cho ai đó.


3
Mặc dù điểm chuẩn này hữu ích, nó không đo mức tiêu thụ bộ nhớ, cũng không tính đến các chuỗi dài, như kbyte hoặc mbyte.

Huh? @ user133408 Chuỗi dài và chuỗi byte lớn hơn thậm chí sẽ mất nhiều thời gian hơn.
NiCk Newman

7

Nhiều nhà phát triển sử dụng strposcho các mục đích tối ưu hóa vi mô .

Việc sử dụng strstrcũng chỉ hoạt động nếu chuỗi kết quả không thể được hiểu là sai trong ngữ cảnh boolean.


11
Nó không phải là tối ưu hóa vi mô, nó được gọi là sử dụng đúng chức năng cho công việc . Nếu tôi muốn vị trí của chuỗi, tôi gọi strpos(). Nếu tôi muốn chuỗi con sau vị trí đó, tôi sẽ gọi strstr().
Alnitak

1
@Alnitak: Những gì tôi đã nói. Nếu bạn muốn kiểm tra sự hiện diện của một chuỗi, thì có một hàm cho điều đó. Nếu bạn thực sự cần vị trí, thì có một vị trí khác. - Khi bạn thăm dò để tìm vị trí mà không thực sự cần đến vị trí đó, thì khó có thể "sử dụng đúng chức năng cho công việc". Mục đích rõ ràng là tối ưu hóa vi giây. (Đó không phải là những gì bạn đã trích dẫn?)
mario

1
@mario nhưng không có chức năng nào có mục đích duy nhất là kiểm tra xem chuỗi con có tồn tại hay không. Vị trí của chuỗi con (nếu được tìm thấy) là thông tin miễn phí sau khi bạn thực sự tìm thấy nó. OTOH, strstrlàm được nhiều hơn mức cần thiết, đó là lý do tại sao nó chậm hơn.
Alnitak

@Alnitak: Phiền bạn, không phải tin tức. Bạn có vẻ rất kiên quyết khi chỉ ra sự khác biệt về hiệu suất và chỉ có vậy. Đó là một dấu hiệu cho thấy sự tối ưu hóa vi mô. Nó không tạo ra một đốm sáng trong bộ hồ sơ . Nơi nó tạo ra sự khác biệt là ở khả năng đọc mã.
mario

@mario thực sự tôi chỉ quan tâm một chút đến hiệu suất. Tôi thực sự quan tâm rất nhiều đến việc sử dụng đúng chức năng cho công việc ;-)
Alnitak

0

strpos () phát hiện vị trí của một cây kim cụ thể trong đống cỏ khô. stristr () kiểm tra xem kim có ở bất kỳ đâu trong đống cỏ khô hay không

therefor strpos () nhanh hơn và ít tốn bộ nhớ hơn

một lý do cho strstr (): nếu kim của bạn ở đầu một chuỗi, strpos trả về 0 (vì vậy phải kiểm tra nó với === false)


6
đó là một lời giải thích hoàn toàn không có thật - strstr()trả về mọi thứ trước hoặc sau kim, vì vậy trước tiên nó phải làm tương đương với strpos() và sau đó tạo chuỗi con đó . Đó là nơi đạt được hiệu suất.
Alnitak

-2

Tôi thích tính strstr()dễ đọc và mã hóa dễ dàng .. strpos() !==false hơi khó hiểu ..


1
strstrlà quá tương tự nhưstrtr
Mārtiņš Briedis

strstrcũng cần so sánh chặt chẽ Ví dụ:('123450', '0')
Elvis Ciotti
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.