lsaslında dosyaları sıralar ve bir dizinde bir milyondan fazla dosyayı listelemeye çalışıyorsak, bu büyük bir yük haline gelir. Bu linkte de belirtildiği gibi , dosyaları kullanabiliriz straceveya kullanabiliriz find. Ancak, bu seçenekler de 5 milyon dosyama sahip olduğum için sorunum için uygun değildi. Googling bazı Biz bunu biraz kullandığımız dizinleri listelemek eğer bulundu getdents(), bunun nedeni, daha hızlı olması gerekiyordu ls, findve Pythonkütüphaneler kullanmak readdir()yavaştır fakat kullandığı getdents()altında.
Biz kullanarak dosyaları listelemek için C kodu bulabilirsiniz getdents()dan burada :
/*
* List directories using getdents() because ls, find and Python libraries
* use readdir() which is slower (but uses getdents() underneath.
*
* Compile with
* ]$ gcc getdents.c -o getdents
*/
#define _GNU_SOURCE
#include <dirent.h> /* Defines DT_* constants */
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)
struct linux_dirent {
long d_ino;
off_t d_off;
unsigned short d_reclen;
char d_name[];
};
#define BUF_SIZE 1024*1024*5
int
main(int argc, char *argv[])
{
int fd, nread;
char buf[BUF_SIZE];
struct linux_dirent *d;
int bpos;
char d_type;
fd = open(argc > 1 ? argv[1] : ".", O_RDONLY | O_DIRECTORY);
if (fd == -1)
handle_error("open");
for ( ; ; ) {
nread = syscall(SYS_getdents, fd, buf, BUF_SIZE);
if (nread == -1)
handle_error("getdents");
if (nread == 0)
break;
for (bpos = 0; bpos < nread;) {
d = (struct linux_dirent *) (buf + bpos);
d_type = *(buf + bpos + d->d_reclen - 1);
if( d->d_ino != 0 && d_type == DT_REG ) {
printf("%s\n", (char *)d->d_name );
}
bpos += d->d_reclen;
}
}
exit(EXIT_SUCCESS);
}
Yukarıdaki C programını, dosyaların listelenmesi gereken dizine kopyalayın. Ardından aşağıdaki komutları yürütün.
gcc getdents.c -o getdents
./getdents
Zamanlama örneği : sistem yapılandırmasına bağlı olarak, getdentsçok daha hızlı olabilir ls -f. Hesaplama kümesindeki NFS bağlacı üzerinde yaklaşık 500k dosya içeren bir dizini listelemek için 40x hız artışı gösteren bazı zamanlamalar. Her komut ilk önce hemen getdentsardından 10 kez çalıştırıldı ls -f. İlk çalıştırma, muhtemelen NFS önbellek sayfası hataları nedeniyle, diğerlerinden önemli ölçüde daha yavaştır. (Bir kenara: bu bağın üzerinden d_type, birçok dosya "bilinmeyen" tür olarak göründüğü için , alan güvenilir değildir.)
command: getdents $bigdir
usr:0.08 sys:0.96 wall:280.79 CPU:0%
usr:0.06 sys:0.18 wall:0.25 CPU:97%
usr:0.05 sys:0.16 wall:0.21 CPU:99%
usr:0.04 sys:0.18 wall:0.23 CPU:98%
usr:0.05 sys:0.20 wall:0.26 CPU:99%
usr:0.04 sys:0.18 wall:0.22 CPU:99%
usr:0.04 sys:0.17 wall:0.22 CPU:99%
usr:0.04 sys:0.20 wall:0.25 CPU:99%
usr:0.06 sys:0.18 wall:0.25 CPU:98%
usr:0.06 sys:0.18 wall:0.25 CPU:98%
command: /bin/ls -f $bigdir
usr:0.53 sys:8.39 wall:8.97 CPU:99%
usr:0.53 sys:7.65 wall:8.20 CPU:99%
usr:0.44 sys:7.91 wall:8.36 CPU:99%
usr:0.50 sys:8.00 wall:8.51 CPU:100%
usr:0.41 sys:7.73 wall:8.15 CPU:99%
usr:0.47 sys:8.84 wall:9.32 CPU:99%
usr:0.57 sys:9.78 wall:10.36 CPU:99%
usr:0.53 sys:10.75 wall:11.29 CPU:99%
usr:0.46 sys:8.76 wall:9.25 CPU:99%
usr:0.50 sys:8.58 wall:9.13 CPU:99%
lsBu kullanımlar için bir takma adınızın olmadığından--colorveya-Fbununlstat(2)her bir dosya için a yapmak anlamına geldiğinden emin olun .