유니버스의 벤치마킹 읽기
4749 단어 javascriptperformancenode
한 가지 해결책은 자바스크립트가 아닌 C로 모든 읽기를 수행하는 것이라고 생각하지만 최적화를 시작하기 전에 유효성을 검사하는 것이 좋습니다.
따라서 첫 번째 단계는 BASIC이 얼마나 빠른지 확인하는 것입니다. 이것이 가장 빠른 옵션일 것입니다.
기본 테스트
내가 실행할 테스트는 각각 200개의 필드가 있는 약 95,000개의 레코드가 있는 파일을 선택하는 것입니다. 하지만 그 중 150개만 지속적으로 채워집니다.
OPEN '','INVENTORY-FILE' TO INVENTORY.FILE ELSE
PRINT 'Unable to open file: INVENTORY-FILE - Press RETURN':
INPUT ANYTHING
STOP
END
*
BUFFER = ''
*
SELECT INVENTORY.FILE
*
LOOP
READNEXT ITEM.ID ELSE ITEM.ID = ''
UNTIL ITEM.ID = '' DO
READ INVENTORY.ITEM FROM INVENTORY.FILE, ITEM.ID ELSE INVENTORY.ITEM = ''
BUFFER<-1> = LOWER(INVENTORY.ITEM)
REPEAT
*
PRINT 'Items: ' : DCOUNT(BUFFER, @AM)
이것은 매우 간단한 프로그램입니다. 인벤토리 파일을 열고 선택한 다음 모든 레코드를 버퍼로 읽어 들입니다.
시간이 얼마나 걸리는지 확인하기 위해 Linux 명령줄에서 시간을 몇 번 사용하고 대충 추측해 보겠습니다.
> time uv "RUN BP TEST.READS"
이는 다음과 같은 일반적인 결과를 제공합니다.
bash-4.2$ time uv "RUN BP TEST.READS"
Items: 94872
real 0m0.522s
user 0m0.285s
sys 0m0.241s
bash-4.2$ time uv "RUN BP TEST.READS"
Items: 94872
real 0m0.510s
user 0m0.284s
sys 0m0.230s
여기서 놀라운 점은 READ 문을 MATREAD로 변경하면 프로그램 실행 시간이 길어진다는 것입니다. 배열의 크기를 지정하는 것이 더 빠를 것이라고 생각했지만 실제로는 더 길어집니다.
배열의 크기를 지정하는 것은 실제로 200개의 변수를 선언하고 레코드를 읽는 것은 각 필드를 변수 중 하나에 할당하는 것과 관련되기 때문일 수 있습니다. 대, 내가 가정하는 READ를 사용하면 필드에 대해 인덱싱된 메모리의 큰 청크 1개를 사용합니다.
MATREAD는 약 1.2초 내에 실행되는 반면 READ는 0.52초 내에 실행됩니다. 매우 흥미롭고 이 성능 테스트를 실행하게 되어 이미 기쁩니다.
부록
전체 데이터를 버퍼에 추가하는 것보다 특정 값을 버퍼로 읽는 데 시간이 더 걸렸습니다. 일리가 있는 일이지만 무슨 일이 일어나고 있는지 궁금합니다. 비용이 그렇게 많이 들 줄은 몰랐는데 처음 2개 값만 읽어도 터무니없이 비쌌습니다. 한 가지 이유는 유니버스가 문자열 구문 분석을 사용하여 값을 가져오기 때문일 수 있습니다. 읽기를 수행하고 있기 때문에 개별 값을 얻는 데 훨씬 더 빠르지만 변수를 설정하는 비용이 있는 MATREAD와 비교하여 각 항목을 구문 분석해야 할 수 있습니다.
이것은 READ가 데이터를 빨리 가져오는 데는 좋지만 처리하기 어려운 반면 MATREAD는 데이터를 가져오는 데 느리지만 처리하는 데 빠르다는 재미있는 작은 점입니다.
이제 제가 할 수 있는 최선의 가정은 이 BASIC 프로그램입니다. 노드 버전은 확실히 더 오래 걸립니다.
테스트 노드
노드 버전에는 몇 가지 눈에 띄는 문제가 있습니다. 첫 번째는 읽을 때마다 javascript에서 C로 넘어가는 것입니다. 이것은 비싸야 합니다. 다음 문제는 각 읽기가 RPC 포트를 거쳐야 한다는 것입니다. localhost에서는 괜찮을 수 있지만 멀리 떨어진 서버에서는 네트워크 시간이 킬러가 됩니다.
const mv = require("pick-mv");
const Universe = require('pick-universe');
const uv = new Universe("localhost", "user", "password", "/path/to/account");
uv.StartSession();
const INV = uv.Open("INVENTORY-FILE");
uv.Select(INV);
let buffer = [];
while (true) {
let id = uv.ReadNext();
if (id === null) break;
let record = uv.Read(id, INV);
buffer.push(record);
}
uv.EndAllSessions();
console.log(`Items: ${buffer.length}`);
BASIC과 노드 버전이 거의 동일하고 라인 수가 같은 범위에 있다는 점이 마음에 듭니다.
성능 테스트는 localhost에서 진행됩니다.
bash-4.2$ time node test.js
Items: 94873
real 0m7.528s
user 0m1.610s
sys 0m2.391s
bash-4.2$
확실히 더 깁니다! 15배 더 길다. 이것은 또한 네트워크를 통해 크게 올라갑니다. 나는 거의 15분을 기다렸지만 테스트를 종료했을 때 여전히 끝나지 않았습니다.
이것은 기본적으로 네트워크에서 노드 라이브러리를 사용하는 것이 의미가 없으며 작업을 수행하고 데이터를 반환하기 위해 서버에서 서브루틴을 호출하는 것이 더 낫다는 것을 의미합니다.
우리가 할 수 있는 변화는 readlist를 사용하여 한 번에 모든 ID를 읽는 것입니다. 이제 레코드 읽기를 위해 C로 돌아가기만 하면 되므로 속도가 빨라집니다.
const mv = require("pick-mv");
const Universe = require('./index');
const uv = new Universe("localhost", "user", "password", "/path/to/account");
uv.StartSession();
const INV = uv.Open("INVENTORY-FILE");
uv.Select(INV);
let buffer = [];
let ids = mv.MVToArray(uv.ReadList());
for (let id of ids) {
let record = uv.Read(id, INV);
buffer.push(record);
}
uv.EndAllSessions();
console.log(`Items: ${buffer.length}`);
소요 시간:
bash-4.2$ time node test.js
Items: 94873
real 0m4.818s
user 0m1.267s
sys 0m1.331s
이것은 우리가 javascript에서 readnexts를 수행할 때 얻은 7.5초보다 약간 낫지만 여전히 상당히 느립니다.
이제 증거가 있으므로 C에 머물면서 레코드 목록을 배열로 읽은 다음 해당 배열을 노드로 반환하는 ReadAll 함수를 작성하려고 합니다. 이것은 여전히 네트워크 호출을 수행하므로 Universe 서버가 localhost에서 실행되고 있는지 확인하는 더 깊은 문제를 해결할 것이라고 생각하지 않습니다.
Reference
이 문제에 관하여(유니버스의 벤치마킹 읽기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/krowemoh/benchmarking-reads-in-universe-17ba텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)