angular-restmod icon indicating copy to clipboard operation
angular-restmod copied to clipboard

Performance of $scope on large datasets

Open facultymatt opened this issue 10 years ago • 5 comments

I'm doing some heap debugging in Chrome... I noticed one of the largest retained constructors was a restmod collection of a few hundred objects.

Specifically, the retained size is in the $scope property.

scope_1

I wanted to start a discussion around this...

  • Is $scope needed? If so, what is its purpose?
  • Is $scope being properly garbage collected within the restmod library?
  • Could I be using restmod collections in a way that prevents garbage collection?

facultymatt avatar Jan 19 '15 14:01 facultymatt

Could you share some information about your model structure?

Each record/collection has a $scope property that holds the parent scope.

The first thing that comes to mind is that you are calling $search on a collection and then $search again on the resulting collection and then $search again on the result and so on. Each time you call $search on a given collection a new child collection is created and its $scope property is assigned the initial collection, preventing the GC from collecting the parent collection. For example, if you call test = Model.$seach().$seach().$seach().$seach().$seach().$seach() you will be left with 5 referenced collections (non collectable) and test.$scope will show a bigger than usual heap size.

iobaixas avatar Jan 21 '15 14:01 iobaixas

But in this example, if you set test = null; then then the referenced collections can be garbage collected, correct?

facultymatt avatar Jan 21 '15 23:01 facultymatt

Roughly, my model configuration is as follows

  • Trip hasMany points
  • Point hasOne sensorData
  • Point hasOne wheelData
  • Trips can have anywhere from 100 - 10,000 points.
  • Point model has many filtering methods that use $asList()
angular
  .module('SPModels')
  .factory('Trip', function(restmod) {
    return restmod.model('/trips').mix({
      $config: {
        primaryKey: 'tripId'
      },
      name: '',
      points: {
        hasMany: 'Point',
        path: 'points',
        inverseOf: 'trip'
      }
    });
  });

angular
  .module('SPModels')
  .factory('Point', function(restmod) {
    return restmod.model('/points').mix({
      $config: {
        primaryKey: 'pointId'
      },
      location: {
        decode: 'DecodeGeoJSONPoint'
      },
      sensorData: {
        hasOne: 'SensorData',
        inverseOf: 'point'
      },
      wheelData: {
        hasOne: 'WheelData',
        inverseOf: 'point'
      },
      trip: {
        belongsTo: 'Trip'
      },
      $extend: {
        List: {
          sampleBy: function(sampleAmt) {
            sampleAmt = sampleAmt || 10;
            return this.$asList(function(_things) {
              return _things.slice(-sampleAmt);
            });
          }
        }
      }
    });
  });

angular
  .module('SPModels')
  .factory('WheelData', function(restmod) {
    return restmod.model(null).mix({
      point: {
        belongsTo: 'Point'
      },
      speed: {
        init: 0,
        decode: 'DecodeNumber'
      },
      totalOdometer: {
        init: 0,
        decode: 'DecodeNumber'
      },
      tripOdometer: {
        init: 0,
        decode: 'DecodeNumber'
      }
    });
  });

angular
  .module('SPModels')
  .factory('SensorData', function(restmod) {
    return restmod.model(null).mix({
      point: {
        belongsTo: 'Point'
      }
    });
  });

And some example controller code is below:

// get trips
$scope.trips = Trip.$search();

// active trip, and fetch its points
$scope.activate = function(trip) {
  $scope.activeTrip = trip;
  $scope.activeTrip.points.$fetch();
};

// get last 10 points from active trip
$scope.sample = function() {
  $scope.sampled = $scope.activeTrip.points.sampleLast(10);
}

facultymatt avatar Jan 21 '15 23:01 facultymatt

Any suggestions here?

facultymatt avatar Feb 03 '15 15:02 facultymatt

Maybe you could check how many levels of nested scopes (and their types/contents) are held by the offending object? Just to check if the problem is some unnecessary collection chaining?

iobaixas avatar Feb 05 '15 23:02 iobaixas