Home > Blockchain >  Loading large (static) datastructures dynamically
Loading large (static) datastructures dynamically

Time:09-28

I have a quite large datastructure that I would like to load (from the bundle to memory). My requirements are the following:

  • This should take place in the background (non-blocking), not delaying the app starting time and not freezing the app after it loaded.
  • The data is not required right away, so there is plenty of time to load it.
  • Data loading should start as soon as possible.

Current test

For now I have something quite basic but it doesn't fit my requirements. It looks like this:

// `data.ts` File containing my maps
const testMap: Map<string, Content> = new Map([
    ["k1_2", {"a": 1, "b": 2}],
    ["k10_20", {"a": 10, "b": 20}],
]);
import React, { useState } from 'react';
import { Text } from 'react-native';
import { map } from './data';

const TEST_A = 500;
const TEST_B = 100;

function TestLoadingDataStructure() {
    const [duration, setDuration] = useState('-');
    const [valid, setValid] = useState(false);

    function runTest() {
        const startTime = new Date();
        const values = testMap.get(`k${TEST_A}_${TEST_B}`);
        const endTime = new Date();
        const duration = endTime - startTime;
        if (duration > 1000) {
            setDuration(`${duration / 1000} seconds`);
        } else {
            setDuration(`${duration} ms.`);
        }
        setValid(values.a * values.b === TEST_A * TEST_B);
    }

    return (
        <Text onPress={runTest}>
            Test, durée ={' '}
            <Text
                style={{ color: valid ? 'green' : 'red' }}
            >
                {duration}
            </Text>
        </Text>
    );
}

If you use this component and click the text, the first time you press it it will take a long time (on my phone it takes approximately 5 seconds). The second time I press it, it takes less than 1 ms.

My goal is to have this take 1ms even the first time. For this I need to load my data before the component loads (I guess?). I could do this by adding this line at the top of my component file:

testMap.get(`k1_1`);

function TestLoadingDataStructure() {...}

But doing that slows down the app loading, so I though this could be solved by loading dynamically, like so:

setTimeout(() => {
    testMap.get(`k1_1`);
}, 1000);

But this freezes the application when the timeout triggers.

The questions

  1. Is there a nice way of loading the data in the background?
  2. Is storing the data in a plain text file a good idea?
  3. Any other suggestion is welcome, I'm realy uncertain about all this and I don't know what to search for.

Test data

If you want some data that looks a bit like the real one (shape and size) you can test with this:

echo "export const testMap = new Map([" > data.ts
for i in {1..1000} 
  do for j in {1..200}
    do echo "\t[\"k${i}_${j}\", { \"a\": $i, \"b\": $j }],"
  done
done >> data.ts
echo "]);" >> data.ts

CodePudding user response:

As discussed in the comments, storing the static data in a file that has to be parsed in full before it can be used (e.g. a JavaScript/TypeScript module, or a JSON file in the bundle) does not sound like a great idea.

Instead you'll want a format that doesn't need to be read to memory to access a single key, and an SQLite database fits that bill well. You can use e.g. react-native-sqlite-storage to access a pre-populated database.

If, for some reason, you couldn't use SQLite, you could of course roll a database format of your own (e.g. JSONL/ND-JSON might be a good record format), but it'll be slower and more work for you.

  • Related