ls
প্রকৃতপক্ষে ফাইলগুলি বাছাই করে সেগুলি তালিকাভুক্ত করার চেষ্টা করে যা আমরা যদি কোনও ডিরেক্টরিতে এক মিলিয়নেরও বেশি ফাইল তালিকাভুক্ত করার চেষ্টা করি তবে এটি একটি বিশাল ওভারহেড হয়ে যায়। এই লিঙ্কে উল্লিখিত হিসাবে , আমরা ফাইলগুলি ব্যবহার করতে strace
বা find
তালিকা করতে পারি। যাইহোক, আমার কাছে 5 মিলিয়ন ফাইল থাকার কারণে এই বিকল্পগুলিও আমার সমস্যার কাছে অপরিহার্য বলে মনে হয়েছিল। Googling কিছু বিট পর, আমি দেখা গেছে যে যদি আমরা ব্যবহার ডিরেক্টরি তালিকা getdents()
, এটি দ্রুত হবে, কারণ অনুমিত হয় ls
, find
এবং Python
লাইব্রেরি ব্যবহার readdir()
যা ধীর কিন্তু ব্যবহার getdents()
নীচে।
আমরা এখানgetdents()
থেকে ফাইলগুলি তালিকাবদ্ধ করতে সি কোড খুঁজে পেতে পারি :
/*
* 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
। এখানে একটি সময় গণনা ক্লাস্টারে একটি এনএফএস মাউন্টে প্রায় 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)
প্রতিটি ফাইলের জন্য একটি করছেন doing