ls
वास्तव में फाइलें छांटते हैं और उन्हें सूचीबद्ध करने की कोशिश करते हैं जो एक विशाल ओवरहेड बन जाता है यदि हम एक निर्देशिका के अंदर एक लाख से अधिक फाइलों को सूचीबद्ध करने की कोशिश कर रहे हैं। जैसा कि इस लिंक में बताया गया है , हम फ़ाइलों का उपयोग strace
या find
सूचीबद्ध कर सकते हैं। हालाँकि, वे विकल्प भी मेरी समस्या के लिए प्रतिकूल थे क्योंकि मेरे पास 5 मिलियन फाइलें थीं। कुछ गुगली करने के बाद, मैंने पाया कि यदि हम निर्देशिकाओं का उपयोग करते हुए सूचीबद्ध करते हैं getdents()
, तो यह तेज़ होना चाहिए, क्योंकि ls
, find
और Python
पुस्तकालयों का उपयोग readdir()
धीमा है, लेकिन getdents()
नीचे का उपयोग करता है।
हम यहाँgetdents()
से उपयोग कर फाइलों को सूचीबद्ध करने के लिए C कोड पा सकते हैं :
/*
* 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);
}
सी प्रोग्राम को उपरोक्त निर्देशिका में कॉपी करें जिसमें फ़ाइलों को सूचीबद्ध करने की आवश्यकता है। फिर नीचे दिए गए कमांड को निष्पादित करें।
gcc getdents.c -o getdents
./getdents
समय का उदाहरण : सिस्टम कॉन्फ़िगरेशन पर निर्भर करते हुए, getdents
बहुत तेजी से हो सकता ls -f
है। यहाँ कुछ समय एक कम्प्यूटेशन क्लस्टर में NFS माउंट पर 500k फ़ाइलों वाली निर्देशिका को सूचीबद्ध करने के लिए 40x की गति वृद्धि का प्रदर्शन कर रहे हैं। प्रत्येक कमांड को तत्काल उत्तराधिकार में 10 बार चलाया गया था, पहले getdents
, फिर ls -f
। पहला रन अन्य सभी की तुलना में काफी धीमा है, शायद एनएफएस कैशिंग पेज दोष के कारण। (एक तरफ: इस माउंट पर, d_type
क्षेत्र अविश्वसनीय है, इस अर्थ में कि कई फाइलें "अज्ञात" प्रकार के रूप में दिखाई देती हैं)
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%
ls
उस उपयोग के लिए कोई अन्य नाम नहीं है--color
या-F
इसका मतलब है किlstat(2)
प्रत्येक फ़ाइल के लिए करना होगा ।