Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Nivethan
Nivethan

Posted on • Edited on

     

Benchmarking Reads in Universe

I have plans to use my node pick-universe library but one thing that weighs it down is that reading entire files is a pretty expensive operation. Reading a single record is slow but I can deal with it. However selecting a file of 100k items and reading in everything is slow.

I think one solution would be to do all the reads in C rather than in javascript but before I start trying to optimize it's probably a good idea to validate things.

So the first step is to see how fast BASIC is. This would be the fastest option most likely.

Testing BASIC

The test I'll be running will be selecting a file with about 95k records with 200 fields each. Only 150 of them are populated consistently though.

      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)
Enter fullscreen modeExit fullscreen mode

This is a pretty simple program. It simply opens the inventory file, selects it, and then reads in every record into a buffer.

To see how long it takes, I simply use time from the linux commandline a few times and I'll take a rough guess of it.

> time uv "RUN BP TEST.READS"
Enter fullscreen modeExit fullscreen mode

This gives a general result of:

bash-4.2$ time uv "RUN BP TEST.READS"Items: 94872real    0m0.522suser    0m0.285ssys     0m0.241sbash-4.2$ time uv "RUN BP TEST.READS"Items: 94872real    0m0.510suser    0m0.284ssys     0m0.230s
Enter fullscreen modeExit fullscreen mode

Surprising note here is that changing the READ statement to a MATREAD makes the program run longer. I thought dimensioning an array would be faster but it actually makes it longer.

This is probably because dimensioning an array is really declaring 200 variables and reading a record involves allocating each field to one of the variables. Versus, using READ which I assume uses 1 big chunk of indexed memory for the fields.

MATREAD run in about 1.2 seconds whereas the READ runs in 0.52. Very interesting and I'm already glad to have run this performance test.

Addendum

Reading specific values into a buffer took longer than just adding the entire data to the buffer. Sort of makes sense but I'm curious what's going on. I didn't think the cost would be so much but reading just the first 2 values was stupidly expensive. One reason could be because universe uses string parsing to get the values. It could be that because I'm doing a read, I need to parse each thing versus MATREAD which would be far quicker for getting individual values but has the cost of setting up the variables.

This is a fun little point where READ is great to get the data quickly but hard to handle whereas MATREAD is slower to get the data but fast to handle.

Now the assumption I'm going with is that the best we can do is this BASIC program. The node version definitely takes longer.

Testing Node

The node version has some glaring issues. The first is that I cross from javascript to C for every read. This has to be expensive. The next issues is that each Read requires going over the RPC port. On localhost, it's probably fine but on a faraway server the network time would be killer.

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}`);
Enter fullscreen modeExit fullscreen mode

I do like that the BASIC and node versions are almost identical and the line counts are in the same range.

The performance test, this will be on localhost:

bash-4.2$ time node test.jsItems: 94873real    0m7.528suser    0m1.610ssys     0m2.391sbash-4.2$
Enter fullscreen modeExit fullscreen mode

It is definitely longer! 15x longer. This also goes up drastically over the network. I waited almost 15 minutes and still hadn't finished when I killed my test.
This basically means that using the node library probably makes 0 sense over the network and it would be better to simply call a subroutine on the server to do the work and return the data.

A change we can do is to use readlist to read in all the ids in one shot. This should speed things up as now we only need to go back to C for the record reads.

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}`);
Enter fullscreen modeExit fullscreen mode

This takes:

bash-4.2$ time node  test.jsItems: 94873real    0m4.818suser    0m1.267ssys     0m1.331s
Enter fullscreen modeExit fullscreen mode

This is a bit better than the 7.5 seconds we had from doing the readnexts in javascript but it's still quite slow.

Now that we have proof, I'm going to take a stab at writing a ReadAll function that will stay in C and read a list of records into an array and then return that array to node. This still does the network call so I don't think it'll solve the deeper issue of making sure the Universe server is running on localhost.

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

  • Joined

More fromNivethan

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp