Uploaded image for project: 'Realm JavaScript SDK'
  1. Realm JavaScript SDK
  2. RJS-442

Poor insertion performance 10k+ records

      <!---

      Questions: If you have questions about HOW TO use Realm, please ask on
      StackOverflow: http://stackoverflow.com/questions/ask?tags=realm
      We monitor the realm tag.

      Feature Request: Just fill in the first two sections below.

      Bugs: To help you as fast as possible with an issue please describe your issue
      and the steps you have taken to reproduce it in as much detail as possible.

      -->

      Goals

      I am trying to understand why the performance of inserts is so poor from a react native environment vs xamarin (using the Realm .Net library).

      My use case is initial syncing a mobile application with a backend of items (things like street data, assets, jobs etc.) that can range from 10-500k records for use offline over the period of a week to later be synced back on completion.

      The .Net library appears to be orders of magnitude faster and has a more linear timing curve for large inserts, realm-js inserts degrade over time given my tests.

      <!--- What are you trying to achieve? -->

      Expected Results

      I am expecting similar performance on inserting many records in the realm-js library as it is in the .Net library.

      <!--- What did you expect to happen? -->

      Actual Results

      Test 1k inserts 10k inserts 100k inserts
      realm-js 0.45s 5.8s 200s
      Realm.Net 0.5s 1.78s 15.4s
      realm-js is... 10% faster 225.8% slower 1198.7% slower
      realm-js (no indices) 0.33s 2.78s 26.9s

      <!--- What happened instead? -->
      <!--- e.g. the stack trace of a crash -->

      Steps to Reproduce

      Attempt to insert a large number of records into a realm.
      <!--- What are steps we can follow to reproduce this issue? -->

      Code Sample

      The following should be copy-pasteable into a brand new react-native app with typescript as the App.ts file. Alternatively the onPress function and models at the end of the code snippet should be all that's necessary.

      The .Net code is almost like for like.

      Unable to find source-code formatter for language: typescript. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
      import React, {Component, Fragment} from 'react';
      import {Button, Alert} from 'react-native';
      import Realm from 'realm';
      
      // test app component
      export default class App extends Component {
        render() {
          return (
            <Fragment>
              <Button title="My Button" onPress={() => this.onPress()} />
            </Fragment>
          );
        }
      
        // run a fake sync
        onPress() {
          requestAnimationFrame(async () => {
            const config: Realm.Configuration = {
              path: 'myDb',
              schema: [ItemSchema],
            };
      
            Realm.deleteFile(config);
      
            // make some items to eventually insert
            const itemsToInsert: Item[] = [];
            for (let i = 0; i < 10000; i++) {
              itemsToInsert.push({
                collection: 'Live',
                colour: '#800855',
                dodiCode: 'designs_myDesign',
                icon: 'icon-teste',
                itemId: '5e4baedd22475918f03acf4a' + i,
                subtitle: 'alright partner',
                title: 'keep on rollin baby!',
              });
            }
      
            const realm = await Realm.open(config);
      
            // start timing
            const start = new Date().getTime();
      
            realm.write(() => {
              for (let i = 0, total = itemsToInsert.length; i < total; i++) {
                realm.create(ItemSchema.name, itemsToInsert[i], Realm.UpdateMode.All);
              }
            });
      
            // end timing
            const end = new Date().getTime();
      
            realm.close();
      
            Alert.alert('finished: ' + (end - start) + 'ms');
          });
        }
      }
      
      // schema for item
      const ItemSchema: Realm.ObjectSchema = {
        name: 'item',
        primaryKey: 'itemId',
        properties: {
          itemId: {
            type: 'string',
            optional: false,
          },
          dodiCode: {
            type: 'string',
            optional: false,
            indexed: true,
          },
          collection: {
            type: 'string',
            optional: false,
          },
          title: {
            type: 'string',
            optional: true,
            indexed: true,
          },
          subtitle: {
            type: 'string',
            optional: true,
          },
          icon: {
            type: 'string',
            optional: true,
          },
          colour: {
            type: 'string',
            optional: true,
          },
        },
      };
      
      // model for item
      interface Item {
        itemId: string;
        dodiCode: string;
        collection: string;
        title: string | null;
        subtitle: string | null;
        icon: string | null;
        colour: string | null;
      }
      

      <!---
      Please provide a code sample or test case that highlights the issue.
      If relevant, include your model definitions.
      For larger code samples, links to external gists/repositories are preferred.
      Full projects that we can compile and run ourselves are ideal!
      -->

      Version of Realm and Tooling

      • Realm JS SDK Version: ^4.0.0-beta.0
      • Node or React Native: React Native
      • Client OS & Version: Android Emulator and Physical Device
      • Which debugger for React Native: None

            Assignee:
            finn.schiermer-andersen@mongodb.com Finn Andersen (Inactive)
            Reporter:
            unitosyncbot Unito Sync Bot
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: