나는 유사 이래 가장 빠른 목록 파충류를 어떻게 썼는가

CODRR 회사 / fdir


⚡ 가장 빠른 디렉터리 파충류와 NodeJS의 globbing 라이브러리입니다.1초 이내에 1m 파일 캡처



NodeJS의 가장 빠른 디렉터리 파충류 & Globber









⚡ 가장 빠른: NodeJS의 세계에서 비교할 수 있는 속도는 없다.그것은 백만 개의 파일을 포함하는 디렉터리를 1초도 안 되는 시간에 쉽게 잡을 수 있다.
💡 매우 간단: fdir 표현 구축기 모드를 사용하여 파충류를 구축하고 코드의 가독성을 높인다.
🤖 제로 의존: fdir NodeJSfdirfs 모듈만 사용합니다.
🕺 놀라운 크기: 크기가 2KB보다 작은 gzipped & minified.
🔥 지원되는 모든 노드 버전: 노드 버전<10에 대한 지원을 포기한 다른 유사한 라이브러리와 달리 path 모든 버전을 지원합니다>=6.
🖮 Hackable: 확장fdir은 매우 간단합니다. 현재 새로운 구축기 API가 생겼습니다.마음대로 해보세요.

지원


Do you like this project? Support me by donating, creating an issue, becoming a stargazer or opening a pull request. Thanks.


🚄 빠른 시작


설치

fdir를 사용하여 설치할 수 있습니다.
$ npm i

If it's not fast, the work is not yet complete.

Said no one ever.

Writing code fast and writing fast code are two very different things. One could even say they are opposites. If you are in the habit of writing code very fast there's a great chance that it will be slow. Writing fast code is not just about choosing the fastest language, the fastest platform, the fastest libraries etc. Anyone could do that. What makes code truly fast is the little things; the loops, the conditionals, the assignments, function calls etc.

소개

I woke up Thursday morning, groggy, upset and very, very sleepy. My head was hurting. I had been coding all night and I had finally finished the first version of fdir; the fastest directory crawler for NodeJS. I opened my laptop after a good breakfast, splendid tea and a nice walk; ran the benchmark again: fdir was up against 13 other contenders. Always fdir would come out on top in both synchronous and asynchronous crawling. But it was not ready yet...

첫 번째 시도

Writing fast code starts from the very first line.

The purpose of fdir is simple; crawl as many directories as possible in as short a time as possible. The first version of fdir used recursion; it went something like this:

Note: This is an overly simplified version.

function sync(dir) {
  const dirents = fs.readdirSync(dir, { withFileTypes: true });
  const paths = [];

  dirents.forEach(dirent => {
    const res = `${dir}${path.sep}${dirent.name}`;
    if (dirent.isDirectory()) {
     sync(res).forEach(push.bind(paths));
    } else {
      paths.push(res);
    }
  });
  return paths;
}
이것은 거의 모든 것을 물리칠 수 있다.별거 아니에요.단지 순환, 귀속 등등일 뿐이다. 그렇다면 무엇이 그것을 모든 것보다 빨리 하는가?
첫 줄.npm.이것은 디렉터리의 모든 항목의 withFileTypes: true 시스템 호출을 건너뛸 수 있도록 합니다.예.너는 속도의 향상을 상상할 수 있다.
이 선은 틀림없이 너를 속옷에서 튀어나오게 할 것이다.왜 안 써요? fs.lstatSync?!
....
const res = `${dir}${path.sep}${dirent.name}`;
....
느리기 때문이다.그것은 단지 사용하는 것보다 훨씬 느리다.나는 그것에 대해 기준 테스트를 진행했다.대략 50퍼센트 느려졌다.

v1 데이텀:



보시다시피 path.joinpath.sep에 가깝습니다. 이것은 유사한 방법을 사용했기 때문입니다.

수비수 도착


토요일 밤I was posting about rrdir.sync on Reddit.2시간 후, fdir 작성자는 비동기적인 성능을 높이기 위해 PR을 열어 라이브러리를 업데이트했다.나는 대량의 재구성fdir을 진행했고 노드 버전 <10에 대한 지원을 추가했기 때문에 그의 PR은 합병할 수 없다.그러나 한 시간 후에 나는 수동으로 그의 라이브러리를 업데이트하고 기준 테스트를 다시 실행했다.

데이텀 복구,bump rrdir,rrdir 추가.흐르다 #2



silverwind
발표 날짜
async rrdir 이걸로 보면 그렇게 나쁘지 않을 것 같아요.
View on GitHub

결과:


비동기식:

동기화:

두 시간 후, rrdir 작가는 공공 관계를 열어 그의 도서관을 기준에 포함시켰다.공공 관계의 제목은'내가 지금 가장 빨리 뛴다'는 것이다.확실히 그렇다.상당한 격차(50%).나야 합병했지.

지금 제가 제일 빠릅니다. #3



simov
발표 날짜
기준 테스트에 감사드립니다.👍
View on GitHub

다시 쓰다


물론 나는 fdir 1위를 차지할 수 없다.나는 밤새도록 가장 빠른 파충류를 썼다.나는 지금 양보할 수 없다.그래서 나는 전체 알고리즘을 다시 썼다.위에서 아래로.이것은 귀속 fs-recursive 을 삭제하고, 그룹 재건을 멈추고, 각각fs-recursive 호출은 하나의 약속만 사용합니다. 코드는 현재 다음과 같이 보입니다.
function sync(dir, options) {
    const paths = [];
    const dirs = [dir];
    var i = 0;
    while (i < dirs.length) {
        const dir = dirs[i];
        const dirents = fs.readdirSync(dir, readdirOpts);
        dirents.forEach(function(dirent) {
            let fullPath = `${dir}${path.sep}${dirent.name}`;
            if (dirent.isDirectory()) {
                dirs.push(fullPath);
            } else {
                paths.push(fullPath);
            }
        });
        ++i;
    }
    return paths;
}
코드는 해석하기 쉽다.우리는 fdir.sync 그룹에 디렉터리를 계속 추가하기 때문에, 더 많은 디렉터리가 없을 때까지 순환은 영원히 끝나지 않을 것이다.그러나 fdir.async는 이미 첫 번째이기 때문에 나는 정말 그것을 더욱 최적화할 필요가 없지만 저항할 수 없다.다수의 그룹을 초기화하는 것을 제외하고 귀속은 속도를 크게 높였고 전체적으로 코드를 매우 깨끗하게 했다(imo).
진정한 도전은 비동기 버전을 최적화하는 것이다.다들 아시다시피 비동기/리셋 함수 순환을 사용하는 것은 상당히 복잡한 문제입니다.이 모든 일이 발생한 후:
function async(dir, options) {
  return new Promise(function(resolve) {
    const paths = [];
    const dirs = [dir];
    let cursor = 0;
    let readCount = 0;
    let currentDepth = options.maxDepth;
    function walk() {
      // cache the total directories before starting the walk
      let total = dirs.length;
      for (; cursor < total; ++cursor) {
        const dir = dirs[cursor];
        fs.readdir(dir, readdirOpts, function(_, dirents) {
          dirents.forEach(function(dirent) {
            let fullPath = `${dir}${path.sep}${dirent.name}`;
            if (dirent.isDirectory()) {
                dirs.push(fullPath);
            } else {
                paths.push(fullPath);
            }
          });
          // check if we have walked all the directories we had
          if (++readCount === total) {
            // check if we got any new ones
            if (dirs.length === cursor) {
              resolve(paths);
            } else {
            // walk again if we have new directories.
              walk();
            }
          }
        });
      }
    }
    walk();
  });
}
이 개념은 dirs과 매우 비슷하지만, 우리는 귀속을 보류했다.나는 귀속을 믿을 수 있는 방법을 찾지 못했다.

결과

fdir.sync이 다시 1위로 돌아왔다.
비동기식:

동기화:

배달


너희들은 줄곧 기다리고 있는 순간이다.배달뭐 공부 해요?저는 없어요. 잠깐만요. 그런데'X가 아니라 Y'같은 수업이 없어요.죄송합니다.성능은 용례에 달려 있기 때문이다.
  • 너무 빨리 쓰지 마세요.너는 그것을 한 번 또 한 번 다시 써야 한다.만약 그것이 큰 코드 라이브러리라면, 그것은 곧 PITA가 될 것이다.따라서 모든 예방 조치를 취하고 모든 최적화를 꼼꼼히 작성해 주십시오.
  • 1밀리초가 중요하다.일반적으로 우리는 최적화가 1밀리초만 증가했다고 해서 최적화를 추가하지 않는다.그런데'물 한 방울, 물 한 방울'맞나요?
  • NodeJS의 속도는 매우 빨라서 성실한 코드만 작성하면 됩니다.그것을 너무 복잡하게 만들지 마라.간단하게 유지하고 빠르게 유지하세요.
  • 기준.기준기준JavaScript는 여러 개의 순환, 교체기 등을 포함하여 한 가지 일을 하는 방법이 많다. 기준 테스트를 하기 전에 가장 빠른 것이 무엇인지 모른다.나는 나의 모든 줄 코드를 위해 기준 테스트를 실행했는데, 이 코드들은 다른 선택이 있을 수 있다.기억해라, 밀리초가 매우 중요하다.
  • 그래도 나는 Y가 아니라 X로 수업을 몇 시간 해야 한다.
  • 가능한 한 적은 조건문을 사용한다.모든 지점은 비용을 증가시킬 것입니다. 비록 엔진이 그것을 최적화시켰지만, 당신은 반드시 조심해야 합니다.
  • 사전 준비 오류.해봐. 비싸.조심해.
  • fdir.sync, fdir, for 모두 매우 빠르다.너한테 맞는 걸 골라.실제로 그것들을 사용해서 어느 것이 당신의 코드를 더 빨리 할 수 있는지 보세요.
  • API를 사용하기 전에 검토하십시오.일반적인 상황에서 API에는 불필요한 호출, 안내, 오류 검사 등을 줄일 수 있는 것들이 있다forEach.
  • 가능한 한 적게 array.reduce 방법을 사용한다.실제로는 되도록 적게 쓴다withFileTypes: true.string 를 패턴에 밀어넣는 것이 strings 를 패턴에 밀어넣는 것보다 훨씬 느리다.이것 괜찮아요?
  • 그럼 지금 무슨 일이 일어났어요?


    좋아, 나는 계속 기준 테스트를 하고 속도를 높이는 방법을 찾을 거야.WebAssembly, Workers 등을 사용해 보겠습니다. 혁신, 나의 친구, 혁신.현재 fdir는 약 900밀리초 안에 약 100만 개의 파일을 잡을 수 있지만, 나는 그것을 500밀리초로 줄이고 싶다.현재 코드는 가능한 한 최적화되었습니다.내가 뭘 시도했는지 봅시다.

    CODRR 회사 / fdir


    ⚡ 가장 빠른 디렉터리 파충류와 NodeJS의 globbing 라이브러리입니다.1초 이내에 1m 파일 캡처



    NodeJS의 가장 빠른 디렉터리 파충류 & Globber









    ⚡ 가장 빠른: NodeJS의 세계에서 비교할 수 있는 속도는 없다.그것은 백만 개의 파일을 포함하는 디렉터리를 1초도 안 되는 시간에 쉽게 잡을 수 있다.
    💡 매우 간단: string 표현 구축기 모드를 사용하여 파충류를 구축하고 코드의 가독성을 높인다.
    🤖 제로 의존: int NodeJSfdirfdir 모듈만 사용합니다.
    🕺 놀라운 크기: 크기가 2KB보다 작은 gzipped & minified.
    🔥 지원되는 모든 노드 버전: 노드 버전<10에 대한 지원을 포기한 다른 유사한 라이브러리와 달리 fdir 모든 버전을 지원합니다>=6.
    🖮 Hackable: 확장fs은 매우 간단합니다. 현재 새로운 구축기 API가 생겼습니다.마음대로 해보세요.

    지원


    Do you like this project? Support me by donating, creating an issue, becoming a stargazer or opening a pull request. Thanks.


    🚄 빠른 시작


    설치

    path를 사용하여 설치할 수 있습니다.
    $npm i…
    View on GitHub
    Support fdir on ProductHunt
    읽어주셔서 감사합니다.
    CODRR 회사

    좋은 웹페이지 즐겨찾기