2017-12-19 26 views
0

자바 스크립트에서 선택한 모든 사용자 파일을 읽고 싶습니다.자바 스크립트에서 메모리로 파일을 읽을 때 좋은 배치 크기를 계산하는 방법은 무엇입니까?

탐색기 변수에서 폴더 선택 입력 필드를 사용하여 파일을 가져오고, 사용 가능한 코어의 양과 gb 단위의 RAM을 얻습니다.

대기열 알고리즘을 사용하고 있으므로 사용 가능한 코어 당 웹 작업자 작업을 만듭니다.

그런 다음 모든 작업자를 반복하고 파일 목록에서 크기를 batch 크기로 잘라서 작업자에게줍니다.

작업자가 작업을 마칠 때마다 더 이상 파일이 남아 있지 않고 모든 작업자가 완료 될 때까지 파일 목록에서 다른 슬라이스 크기 batch을 가져옵니다.

사용할 수있는 값이 batch 인 것을 알아 내는데 문제가 있습니다. 그것은 고정되거나 어떤 공식을 기반으로 할 수 있습니다.

77 파일이있는 경우 일괄 처리 크기가 16으로 작동하고 151324가 있으면 300의 배치 크기가 좋습니다. 그러나 나는 메모리를 죽일 수있는 배치 크기를 선택하는 것을 원하지 않지만, 동시에 더 빠르게 만듭니다.

또한 각 파일에서 최대 75KB를 읽었습니다.

또한 각 파일에는 size 속성이 있습니다. 내가 어떤 선집 작업을한다면, 변화가있을 것인가?

누구든지이 작업을 수행하는 방법을 알고 있습니까?

감사

답변

0

이 테스트 할 가지고 있지만, URL#createObjectURL를 사용하여, 당신은 이론적으로 메인 스레드에서 데이터를 복사하지 않고, 당신의 노동자가 사용할 수있는 디스크의 파일에 직접 포인터를 만들 수 있습니다.

즉, 배치 크기은 간단히 files.length/numberOfWorkers 일 수 있습니다.


A rough proof of concept:
노동자에

(StackSnippet의 널 (null) origined은 iframe이 트릭을 불가능하게하기 때문에 바이올린 ... 등) :

self.onmessage = e => { 
    Promise.all(
    e.data.map(async (url)=> 
     fetch(url).then(r=>r.blob()) 
    // here you can do whatever you have to do with the file 
     .then(file => new FileReaderSync() 
     .readAsText(file.slice(0,75)) 
     ) 
    ) 
) 
    .then(console.log) 
    .catch(console.error); 
}; 
</script> 

메인 페이지에서 :

// workers is an Array containing your WebWorkers 
inp.onchange = e => { 
    const urls = [...inp.files] 
    .map(file => URL.createObjectURL(file)); 
    const batchSize = Math.ceil(urls.length/(navigator.hardwareConcurrency)); 
    workers.forEach((worker, i) => { 
    worker.postMessage(urls.slice(i*batchSize, i*batchSize + batchSize)); 
    }); 
};