{"id":278062,"date":"2016-04-11T20:40:02","date_gmt":"2016-04-11T16:40:02","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=278062"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=278062","title":{"rendered":"\u041f\u0438\u0448\u0435\u043c \u0437\u0430\u043c\u0435\u043d\u0443 find(1) \u043d\u0430 golang \u043f\u043e\u0434 Linux"},"content":{"rendered":"<p>       <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/1b9\/a5d\/461\/1b9a5d46183a47f48f8be1ee4d0055db.png\" align=\"right\" width=\"450\"\/> \u0414\u043b\u044f \u043e\u0434\u043d\u043e\u0439 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0439 \u0443\u0442\u0438\u043b\u0438\u0442\u044b \u043c\u043d\u0435 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u043b\u043e\u0441\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438, \u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 \u0443\u0442\u0438\u043b\u0438\u0442\u043e\u0439 find, \u0438 \u044f \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0441\u044f \u0441 \u043d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u043e\u0439 \u0432\u0435\u0449\u044c\u044e: \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 Open()+Readdir()+Close() \u0432 go \u043e\u0447\u0435\u043d\u044c \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u044b\u043c \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 \u0442\u0435\u043c, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 linux&#8217;\u043e\u0432\u0430\u044f \u0443\u0442\u0438\u043b\u0438\u0442\u0430 find. \u041d\u0430 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u0438\u0434\u0435\u0442\u044c strace \u044d\u0442\u043e\u0439 \u0443\u0442\u0438\u043b\u0438\u0442\u044b. \u041c\u043e\u0436\u043d\u043e \u0432\u0438\u0434\u0435\u0442\u044c, \u0447\u0442\u043e \u043e\u043d\u0430 \u0434\u0435\u043b\u0430\u0435\u0442 \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u0441\u0442\u0440\u0430\u043d\u043d\u044b\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0435 \u0432\u044b\u0437\u043e\u0432\u044b, \u0438 \u0432 \u044d\u0442\u0438\u0445 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0445 \u0432\u044b\u0437\u043e\u0432\u0430\u0445 \u043c\u044b \u0438 \u043f\u043e\u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0430\u043d\u0430\u043b\u043e\u0433 find \u043d\u0430 go, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0434 Linux, \u043d\u043e \u0437\u0430\u0442\u043e \u0441\u043e \u0441\u0440\u0430\u0432\u043d\u0438\u043c\u043e\u0439 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c\u044e.<\/p>\n<p>  <a name=\"habracut\"><\/a>  <\/p>\n<h3>\u041d\u0430\u0438\u0432\u043d\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f<\/h3>\n<p>  \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u00ab\u043d\u0430\u0438\u0432\u043d\u0443\u044e\u00bb \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e find, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0444\u0430\u0439\u043b\u043e\u0432 \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438.<\/p>\n<pre><code class=\"go\">package main import (...)  func readdir(dir string) { \tdh, err := os.Open(dir) \tdefer dh.Close() \tfor { \t\tfis, err := dh.Readdir(10) \t\tif err == io.EOF { \t\t\tbreak \t\t} \t\tfor _, fi := range fis { \t\t\tfmt.Printf(&quot;%s\/%s\\n&quot;, dir, fi.Name()) \t\t\tif fi.IsDir() { \t\t\t\treaddir(dir + &quot;\/&quot; + fi.Name()) \t\t\t} \t\t} \t} }  func main() { \treaddir(os.Args[1]) } <\/code><\/pre>\n<p>  (<a href=\"https:\/\/gist.github.com\/YuriyNasretdinov\/937d7e4448dbab91fcd19c093620ef84\">\u043f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434, \u0441 \u0438\u043c\u043f\u043e\u0440\u0442\u0430\u043c\u0438 \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439 \u043e\u0448\u0438\u0431\u043e\u043a<\/a>)<\/p>\n<p>  \u0415\u0441\u043b\u0438 \u043c\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043c \u044d\u0442\u043e\u0442 \u043a\u043e\u0434, \u0442\u043e \u043e\u043d, \u0431\u0435\u0437\u0443\u0441\u043b\u043e\u0432\u043d\u043e, \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c, \u043d\u043e wall time \u0438 rusage \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0432 3 \u0440\u0430\u0437\u0430 \u0431\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c \u0443 find (\u0440\u0430\u0437\u043d\u0438\u0446\u0430 \u0432 \u043e\u0434\u0438\u043d \u0444\u0430\u0439\u043b \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u0435\u0442\u0441\u044f \u0442\u0435\u043c, \u0447\u0442\u043e \u043c\u044b \u043d\u0435 \u043f\u0435\u0447\u0430\u0442\u0430\u0435\u043c \u0441\u0430\u043c\u0443 \u0437\u0430\u043f\u0440\u043e\u0448\u0435\u043d\u043d\u0443\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e, \u0432 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 find):<\/p>\n<pre><code>$ time find \/path\/to\/dir | wc -l 169561  real\t0m0.333s user\t0m0.104s sys\t0m0.272s  $ time  GOGC=300 .\/find-simple \/path\/to\/dir | wc -l 169560  real\t0m1.160s user\t0m0.540s sys\t0m0.944s <\/code><\/pre>\n<p>  \u0417\u0430\u043c\u0435\u0442\u0438\u043c, \u0447\u0442\u043e system time \u0443\u0436 \u043e\u0447\u0435\u043d\u044c \u0431\u043e\u043b\u044c\u0448\u043e\u0439, \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0431\u0443\u0444\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u044e \u0432\u044b\u0432\u043e\u0434\u0430:<\/p>\n<pre><code class=\"diff\">@@ -7,5 +7,7 @@ import ( +var bufout = bufio.NewWriter(os.Stdout)  func readdir(dir string) { @@ -28,3 +30,7 @@ func readdir(dir string) {                 for _, fi := range fis { -                       fmt.Printf(&quot;%s\/%s\\n&quot;, dir, fi.Name()) +                       bufout.WriteString(dir) +                       bufout.WriteByte('\/') +                       bufout.WriteString(fi.Name()) +                       bufout.WriteByte('\\n')                         if fi.IsDir() { @@ -44,2 +50,3 @@ func main() {         readdir(dir) +       bufout.Flush()  } <\/code><\/pre>\n<p>  (<a href=\"https:\/\/gist.github.com\/YuriyNasretdinov\/623de87bef169d823906d65e52b26826\">\u043f\u043e\u043b\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f<\/a>)<\/p>\n<p>  \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0431\u0443\u0434\u0443\u0442 \u0443\u0436\u0435 \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u043b\u0443\u0447\u0448\u0435, \u043d\u043e \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u0434\u0430\u043b\u0435\u043a\u0438 \u043e\u0442 \u0438\u0434\u0435\u0430\u043b\u0430:<\/p>\n<pre><code>$ time  GOGC=300 .\/find-simple-bufio \/path\/to\/dir | wc -l 169560  real\t0m0.796s user\t0m0.352s sys\t0m0.616s <\/code><\/pre>\n<p>  \u0414\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430, \u0432\u043e\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0434\u043b\u044f <a href=\"https:\/\/gist.github.com\/YuriyNasretdinov\/2f6d12dae627b0b27cee4c8af7f97def\">\u0442\u0430\u043a\u043e\u0439 \u0436\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043d\u0430 PHP<\/a>:<\/p>\n<pre><code>$ php ~\/find-ob.php \/path\/to\/dir | wc -l 169560  real\t0m0.777s user\t0m0.276s sys\t0m0.500s <\/code><\/pre>\n<p>  \u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043d\u0430 PHP \u0434\u0430\u0436\u0435 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u044f\u0435\u0442 \u0438\u0437\u043c\u0435\u0440\u0438\u043c\u043e \u043c\u0435\u043d\u044c\u0448\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432! \u042d\u0442\u043e \u044f\u0432\u043d\u043e \u043d\u0435 \u0442\u043e, \u0447\u0442\u043e \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043e\u0442 \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u043c\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430\u2026<\/p>\n<h3>\u0418\u0437\u0443\u0447\u0430\u0435\u043c \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0435 \u0432\u044b\u0437\u043e\u0432\u044b Linux<\/h3>\n<p>  \u0415\u0441\u043b\u0438 \u0432\u0433\u043b\u044f\u0434\u0435\u0442\u044c\u0441\u044f \u0432 strace \u043e\u0442 find, \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u043e\u043d \u0434\u0435\u043b\u0430\u0435\u0442 getdents64 \u0438 \u043f\u043e\u0447\u0442\u0438 \u043d\u0435 \u0434\u0435\u043b\u0430\u0435\u0442 stat! \u041d\u043e \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u043a\u0430\u043a\u0438\u043c-\u0442\u043e \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0437\u043d\u0430\u0435\u0442, \u043a\u0430\u043a\u0438\u0435 \u0438\u043c\u0435\u043d\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f\u043c. \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0447\u0442\u043e \u044d\u0442\u043e \u0437\u0430 \u0432\u044b\u0437\u043e\u0432 getdents64 \u0442\u0430\u043a\u043e\u0439:<\/p>\n<pre><code>SYNOPSIS        int getdents(unsigned int fd, struct linux_dirent *dirp,                     unsigned int count);  DESCRIPTION        This is not the function you are interested in.  Look at readdir(3) for the POSIX conforming C library interface.  This page documents the bare kernel system call interface. The system call getdents() reads several linux_dirent structures from the directory referred to by the open file descriptor fd into the buffer pointed to by dirp.  The argument count is specifies the size of that buffer.         The linux_dirent structure is declared as follows:             struct linux_dirent { ...                char           d_name[];                char           pad;       \/\/ Zero padding byte *\/                char           d_type;    \/\/ File type (only since Linux 2.6.4            } <\/code><\/pre>\n<p>  \u042d\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u043e, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e! \u0427\u0442\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u043d\u0430 BSD-\u0441\u0438\u0441\u0442\u0435\u043c\u0430\u0445 \u043f\u0440\u0438 \u0447\u0442\u0435\u043d\u0438\u0438 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 \u0442\u043e\u0436\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u043f\u043e\u043b\u0435 \u0441 \u0442\u0438\u043f\u043e\u043c \u0444\u0430\u0439\u043b\u0430 (d_type), \u0434\u043b\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432\u044b\u0445 \u0441\u0438\u0441\u0442\u0435\u043c. \u041d\u0430\u0441 \u0432\u0441\u044f\u0447\u0435\u0441\u043a\u0438 \u043e\u0442\u0433\u043e\u0432\u0430\u0440\u0438\u0432\u0430\u044e\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0439 \u0432\u044b\u0437\u043e\u0432, \u043d\u043e \u0442\u0443 \u0436\u0435 \u0443\u0442\u0438\u043b\u0438\u0442\u0443 find \u044d\u0442\u043e \u043d\u0438 \u043a\u0430\u043f\u0435\u043b\u044c\u043a\u0438 \u043d\u0435 \u0441\u043c\u0443\u0449\u0430\u0435\u0442.<\/p>\n<p>  \u041a\u0430\u043a \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u00ab\u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c\u00bb \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 go \u0442\u043e\u0436\u0435 \u0437\u043e\u0432\u0435\u0442 getdents(2), \u0442\u0430\u043a \u0447\u0442\u043e \u043d\u0430\u043c \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u00ab\u0432\u044b\u0434\u0440\u0430\u0442\u044c\u00bb \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u0438 \u043e\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u0435\u0433\u043e \u043e\u0442 \u0432\u0441\u0435\u0433\u043e \u043b\u0438\u0448\u043d\u0435\u0433\u043e:<\/p>\n<pre><code class=\"go\">package main import (...) var bufout = bufio.NewWriter(os.Stdout)  func readdir(dir string, file string, dirfd int, pathbuf []byte) { \torigbuf := make([]byte, 4096) \/\/ \u0431\u0443\u0444\u0435\u0440, \u043a\u0443\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u0447\u0438\u0442\u0430\u0442\u044c getdents \tdh, err := syscall.Openat(dirfd, file, syscall.O_RDONLY, 0777) \/\/ \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u0444\u0430\u0439\u043b \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 \u043f\u043e \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u043c\u0443 \u043f\u0443\u0442\u0438 \torigpathbuf := pathbuf[0:0] \/\/ \u043d\u0430\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442 \u0431\u0443\u0444\u0435\u0440 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043f\u0443\u0442\u0438 \u0444\u0430\u0439\u043b\u0430, \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u043c \u0435\u0433\u043e  \tfor { \t\tn, errno := syscall.ReadDirent(dh, origbuf) \/\/ \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c getdents \t\tif n &lt;= 0 { \t\t\tbreak \/\/ EOF \t\t}  \t\tbuf := origbuf[0:n] \/\/ \u043d\u0430\u043c \u0432\u0435\u0440\u043d\u0443\u043b\u0438 \u0447\u0438\u0441\u043b\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043d\u044b\u0445 \u0431\u0430\u0439\u0442, \u044d\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c :) \t\tfor len(buf) &gt; 0 {                         \/\/ \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434 \u0432\u044b\u0434\u0440\u0430\u043d \u0438\u0437 \u043a\u043e\u0434\u0430 ParseDirent: \t\t\tdirent := (*syscall.Dirent)(unsafe.Pointer(&buf[0])) \t\t\tbuf = buf[dirent.Reclen:] \t\t\tif dirent.Ino == 0 { \/\/ File absent in directory. \t\t\t\tcontinue \t\t\t} \t\t\tbytes := (*[10000]byte)(unsafe.Pointer(&dirent.Name[0])) \t\t\tname := bytes[0:clen(bytes[:])] \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f clen() \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0434\u043b\u0438\u043d\u0443 \u0441\u0438\u0448\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \t\t\tif len(name) == 1 && name[0] == '.' || len(name) == 2 && name[0] == '.' && name[1] == '.' { \t\t\t\tcontinue \t\t\t}                          \/\/ \u043f\u0438\u0448\u0435\u043c \u043f\u043e\u043b\u043d\u044b\u0439 \u043f\u0443\u0442\u044c \u0432 \u0431\u0443\u0444\u0435\u0440 \u0441 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u043c \u0438\u043c\u0435\u043d\u0435\u043c \u0444\u0430\u0439\u043b\u0430,                         \/\/ \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0432\u044b\u0434\u0435\u043b\u044f\u0442\u044c \u043f\u0430\u043c\u044f\u0442\u044c \u0434\u043b\u044f \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0445 \u043a\u0443\u0441\u043e\u0447\u043a\u043e\u0432 \t\t\tpathbuf = append(pathbuf, dir...) \t\t\tpathbuf = append(pathbuf, '\/') \t\t\tpathbuf = append(pathbuf, file...) \t\t\tdirlen := len(pathbuf)  \t\t\tpathbuf = append(pathbuf, '\/') \t\t\tpathbuf = append(pathbuf, name...) \t\t\tpathbuf = append(pathbuf, '\\n')  \t\t\tbufout.Write(pathbuf)                          \/\/ \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f, \u0441\u043e\u0437\u0434\u0430\u0435\u043c string \t\t\tif dirent.Type == syscall.DT_DIR { \t\t\t\treaddir(string(pathbuf[0:dirlen]), string(name), dh, origpathbuf) \t\t\t}  \t\t\tpathbuf = origpathbuf[0:0] \t\t}  \t\tbuf = origbuf[0:0] \t}  \tsyscall.Close(dh) }  func main() { \tdir := os.Args[1] \tparentDir := filepath.Dir(dir) \tdh, err := os.Open(parentDir) \tpathbuf := make([]byte, 16 * 1024) \treaddir(parentDir, filepath.Base(dir), int(dh.Fd()), pathbuf) \tbufout.Flush() } <\/code><\/pre>\n<p>  (<a href=\"https:\/\/gist.github.com\/YuriyNasretdinov\/a68b6a997216103b13ea0baa4204230f\">\u043f\u043e\u043b\u043d\u044b\u0439 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b, \u0441 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u043e\u0439 \u043e\u0448\u0438\u0431\u043e\u043a \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 clen<\/a>)<\/p>\n<h3>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b<\/h3>\n<p>  \u0421\u043e \u0432\u0441\u0435\u043c\u0438 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f\u043c\u0438 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430 getdents \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0443\u043c\u0435\u043d\u044c\u0448\u0438\u0442\u044c \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0434\u043e \u0442\u0430\u043a\u043e\u0439 \u0441\u0442\u0435\u043f\u0435\u043d\u0438, \u0447\u0442\u043e \u043e\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0431\u044b\u0441\u0442\u0440\u0435\u0435, \u0447\u0435\u043c find:<\/p>\n<pre><code class=\"go\">$ time  GOGC=300 .\/find-simple \/path\/to\/dir | wc -l 169560  real\t0m1.160s user\t0m0.540s sys\t0m0.944s  $ time GOGC=300 .\/find-optimized \/path\/to\/dir | wc -l 169560  real\t0m0.200s user\t0m0.060s sys\t0m0.160s  $ time find \/path\/to\/dir | wc -l 169561  real\t0m0.333s user\t0m0.104s sys\t0m0.272s <\/code><\/pre>\n<p>  \u041f\u043e\u0442\u0440\u0435\u0431\u043b\u0435\u043d\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0438 \u043e\u0431\u0449\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043c\u0435\u043d\u044c\u0448\u0435 \u0432 \u043f\u043e\u043b\u0442\u043e\u0440\u0430 \u0440\u0430\u0437\u0430, \u0447\u0435\u043c \u0443 find. \u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043f\u0440\u0438\u0447\u0438\u043d\u044b \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u0442 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e find \u0432\u044b\u0434\u0430\u0435\u0442 \u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0444\u0430\u0439\u043b\u043e\u0432, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u0434\u043b\u044f \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u0438 \u0441\u043f\u0438\u0441\u043a\u0430.<\/p>\n<p>  \u041e\u0447\u0435\u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0441\u043f\u0438\u0441\u043a\u0430 \u0444\u0430\u0439\u043b\u043e\u0432 \u0438 \u0432\u044b\u0432\u043e\u0434 \u0435\u0433\u043e \u043d\u0430 \u044d\u043a\u0440\u0430\u043d \u043d\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u043e\u0441\u043e\u0431\u043e\u0439 \u0446\u0435\u043d\u043d\u043e\u0441\u0442\u0438, \u043d\u043e \u0442\u0430\u043a\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0443\u0441\u043a\u043e\u0440\u0438\u0442\u044c \u043c\u043d\u043e\u0433\u0438\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u043d\u0430 go, \u043a\u043e\u0442\u043e\u0440\u044b\u0435, \u043a \u043f\u0440\u0438\u043c\u0435\u0440\u0443, <a href=\"https:\/\/github.com\/monochromegane\/the_platinum_searcher\">\u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u0443 grep<\/a> \u0437\u0430 \u0441\u0447\u0451\u0442 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u043d\u0430\u043a\u043b\u0430\u0434\u043d\u044b\u0445 \u0440\u0430\u0441\u0445\u043e\u0434\u043e\u0432 \u043d\u0430 \u0447\u0442\u0435\u043d\u0438\u0435 \u0441\u043f\u0438\u0441\u043a\u0430 \u0444\u0430\u0439\u043b\u043e\u0432 \u0438\u0437 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438.<\/p>\n<p>  <b>\u0421\u0441\u044b\u043b\u043a\u0438:<\/b>  <\/p>\n<ul>\n<li><a href=\"https:\/\/gist.github.com\/YuriyNasretdinov\/937d7e4448dbab91fcd19c093620ef84\">\u043d\u0430\u0438\u0432\u043d\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f<\/a><\/li>\n<li><a href=\"https:\/\/gist.github.com\/YuriyNasretdinov\/623de87bef169d823906d65e52b26826\">\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0431\u0443\u0444\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0432\u044b\u0432\u043e\u0434\u0430<\/a><\/li>\n<li><a href=\"https:\/\/gist.github.com\/YuriyNasretdinov\/2f6d12dae627b0b27cee4c8af7f97def\">\u0430\u043d\u0430\u043b\u043e\u0433 \u043d\u0430 PHP<\/a><\/li>\n<li><a href=\"https:\/\/gist.github.com\/YuriyNasretdinov\/a68b6a997216103b13ea0baa4204230f\">\u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442<\/a><\/li>\n<\/ul>\n<div class=\"clear\"><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habrahabr.ru\/post\/281382\/\"> https:\/\/habrahabr.ru\/post\/281382\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>       <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/1b9\/a5d\/461\/1b9a5d46183a47f48f8be1ee4d0055db.png\" align=\"right\" width=\"450\"\/> \u0414\u043b\u044f \u043e\u0434\u043d\u043e\u0439 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0435\u0439 \u0443\u0442\u0438\u043b\u0438\u0442\u044b \u043c\u043d\u0435 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u043b\u043e\u0441\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0432 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438, \u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 \u0443\u0442\u0438\u043b\u0438\u0442\u043e\u0439 find, \u0438 \u044f \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0441\u044f \u0441 \u043d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u043e\u0439 \u0432\u0435\u0449\u044c\u044e: \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 Open()+Readdir()+Close() \u0432 go \u043e\u0447\u0435\u043d\u044c \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u044b\u043c \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 \u0442\u0435\u043c, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 linux&#8217;\u043e\u0432\u0430\u044f \u0443\u0442\u0438\u043b\u0438\u0442\u0430 find. \u041d\u0430 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u0438\u0434\u0435\u0442\u044c strace \u044d\u0442\u043e\u0439 \u0443\u0442\u0438\u043b\u0438\u0442\u044b. \u041c\u043e\u0436\u043d\u043e \u0432\u0438\u0434\u0435\u0442\u044c, \u0447\u0442\u043e \u043e\u043d\u0430 \u0434\u0435\u043b\u0430\u0435\u0442 \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u0441\u0442\u0440\u0430\u043d\u043d\u044b\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0435 \u0432\u044b\u0437\u043e\u0432\u044b, \u0438 \u0432 \u044d\u0442\u0438\u0445 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0445 \u0432\u044b\u0437\u043e\u0432\u0430\u0445 \u043c\u044b \u0438 \u043f\u043e\u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0430\u043d\u0430\u043b\u043e\u0433 find \u043d\u0430 go, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0434 Linux, \u043d\u043e \u0437\u0430\u0442\u043e \u0441\u043e \u0441\u0440\u0430\u0432\u043d\u0438\u043c\u043e\u0439 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c\u044e.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-278062","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/278062","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=278062"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/278062\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=278062"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=278062"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=278062"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}