2012-01-01 38 views
29

1] Chức năng nào nhanh hơn?
2] sự khác biệt là gì?
readdir vs scandir

Differences

1] readdir trả về tên của mục tiếp theo trong danh bạ. Scandir trả về một mảng các tập tin và thư mục từ thư mục.

2] readdir phải có một tài nguyên xử lý mở cho đến khi tất cả các mục được đọc. scandir, có lẽ tạo ra một mảng của tất cả các mục và đóng xử lý resouce?

+0

có thể trùng lặp của [Thư mục để mảng với PHP] (http://stackoverflow.com/questions/2120287/directory-to-array-with-php) – salathe

Trả lời

12

Chỉ cần nhận được kết quả (mà không làm bất cứ điều gì), readdir là một tối thiểu nhanh hơn:

<?php 

$count = 10000; 

$dir = '/home/brati'; 

$startScan = microtime(true); 
for ($i=0;$i<$count;$i++) { 
    $array = scandir($dir); 
} 
$endScan = microtime(true); 


$startRead = microtime(true); 
for ($i=0;$i<$count;$i++) { 
    $handle = opendir($dir); 
    while (false !== ($entry = readdir($handle))) { 
     // We do not know what to do 
    } 
} 
$endRead = microtime(true); 

echo "scandir: " . ($endScan-$startScan) . "\n"; 
echo "readdir: " . ($endRead-$startRead) . "\n"; 

Cung cấp:

== RUN 1 == 
scandir: 5.3707950115204 
readdir: 5.006147146225 

== RUN 2 == 
scandir: 5.4619920253754 
readdir: 4.9940950870514 

== RUN 3 == 
scandir: 5.5265231132507 
readdir: 5.1714680194855 

Sau đó, tất nhiên nó phụ thuộc vào những gì bạn định làm. Nếu bạn phải viết một vòng lặp với scandir(), nó sẽ chậm hơn.

15

Nó thực sự phụ thuộc vào những gì bạn đang làm với dữ liệu.

Nếu bạn đang đi qua từng mục nhập, bạn nên sử dụng readdir, nếu bạn thực sự cần có danh sách các mục nhập trong bộ nhớ, bạn nên sử dụng scandir.

Không có ý nghĩa sao chép thông tin vào bộ nhớ khi bạn định sử dụng nó theo từng mục. Đánh giá lười biếng chắc chắn là con đường để đi trong trường hợp đó.

Tôi sẽ tưởng tượng rằng scandir chỉ là một trình bao bọc xung quanh cùng một thứ mà readdir đang gọi và do đó sẽ chậm hơn.

2

Đã làm một số so sánh thời gian hơn để đọc toàn bộ cây thư mục với nhiều tập tin và thư mục:

  • cuộc gọi filetype() == "dir" rõ ràng là nhanh hơn so với is_dir() gọi

  • các opendir/readdir gọi là nhanh hơn nhiều so với việc xây dựng RecursiveDirectoryIterator

  • cây thư mục sử dụng cuộc gọi đệ quy sâu đầu tiên hoặc tuyến tính làm cho không có sự khác biệt

Các cuộc thử nghiệm trên, nơi thực hiện trong Windows trên SSD địa phương, địa phương và USB ổ đĩa mạng với kết quả phù hợp. Chạy trên ổ đĩa mạng chậm hơn 180 lần so với ổ đĩa cục bộ - mặc dù gigabit và đơn vị ReadyNAS nhanh khác!

Số lượng mục nhập được xử lý mỗi giây dao động từ 115 với mã chậm nhất tới ổ đĩa mạng tới gần 65 000 cho mã nhanh nhất vào ổ USB 3.0 - do bộ nhớ đệm tất nhiên.

Nhưng sự khác biệt lớn cho ổ đĩa mạng khiến bạn tự hỏi điều gì xảy ra bên trong PHP như lệnh dir đơn giản và ls trong Linux trên cùng một tệp nhanh hơn nhiều.

Để được tiếp tục ...

2

Tôi đã thực hiện một số thử nghiệm. (Nhờ Aufziehvogel xây dựng)

$count = 100000; 

$dir = dirname(__FILE__); 

$startScan = microtime(true); 
for ($i=0;$i<$count;$i++) { 
    $array = scandir($dir); 
} 
$endScan = microtime(true); 

$startRead = microtime(true); 
for ($i=0;$i<$count;$i++) { 
    $handle = opendir($dir); 
    while (false !== ($entry = readdir($handle))) { 
     // We do not know what to do      
    } 
} 
$endRead = microtime(true); 

$startGlob = microtime(true); 
for ($i=0;$i<$count;$i++) { 
    $array3 = glob('*'); 
} 
$endGlob = microtime(true); 

echo "scandir: " . ($endScan-$startScan) . "\n"; 
echo "readdir: " . ($endRead-$startRead) . "\n"; 
echo "glob : " . ($endGlob-$startGlob) . "\n"; 

Linux Server Kết quả:

scandir: 0.82553291320801 
readdir: 0.91677618026733 
glob : 0.76309990882874 

này Reasults từ 4 lõi (8 Chủ đề) intel E3-1240 Cpu linux + máy chủ Apache.

Nhưng kết quả Máy chủ Windows ngược lại. Windows + Apache server - Intel Q8400 4 Core (4 Chủ đề)

Windows Server Kết quả:

$count = 10000; // it was on linux 100000 :) 

scandir: 0.61557507515 
readdir: 0.614650011063 
glob : 1.92112612724 

(thư mục bao gồm 13 file Nếu tập tin này là sự gia tăng, kết quả có thể khác nhau.)

2

tôi biết câu hỏi này có thể không thực tế bây giờ, nhưng để nối thêm tôi đã thực hiện một số thử nghiệm (như Aufziehvogel và Sayahan) với một sự khác biệt nhỏ - trên một thư mục với các tệp nhỏ 1.000.000 (một vài byte).

$dir = dirname(__FILE__) . '/dir'; 

$startScan = microtime(true); 
$array = scandir($dir); 
for ($i = 0, $j = count($array); $i < $j; $i++) { 
    // Code 
} 
$endScan = microtime(true); 
unset($array); 

$startRead = microtime(true); 
$handle = opendir($dir); 
while (false !== ($entry = readdir($handle))) { 
    // Code 
} 
$endRead = microtime(true); 
unset($handle); 
unset($entry); 

$startDir = microtime(true); 
$files = new DirectoryIterator($dir); 
foreach ($files as $file) { 
    // Code 
} 
$endDir = microtime(true); 
unset($files); 

echo 'scandir:   ', ($endScan - $startScan), PHP_EOL; 
echo 'readdir:   ', ($endRead - $startRead), PHP_EOL; 
echo 'DirectoryIterator: ', ($endDir - $startDir), PHP_EOL; 

Kết quả (HDD):

scandir:   1.9403479099274 
readdir:   0.79462885856628 
DirectoryIterator: 0.5853099822998 

Kết quả (SSD):

scandir:   0.83593201637268 
readdir:   0.35835003852844 
DirectoryIterator: 0.28022909164429 

CPU: AMD A10-4600M APU với Radeon (tm) HD Graphics (4 lõi)
MEM: 8G
PHP: 5.6.29

Các vấn đề liên quan