liquidcarrot / carrot

🥕 Evolutionary Neural Networks in JavaScript
https://liquidcarrot.io/carrot/
MIT License
295 stars 34 forks source link

Weird Node.js Memory-Instantiation Bug #190

Open luiscarbonell opened 5 years ago

luiscarbonell commented 5 years ago

When creating flat networks with the following code (below) - Node.js "chokes" the rate at which it scales after a certain number of connections.

Connections Created (in Thousands) Elapsed Time (in Milliseconds)
100 761
110 675
120 788
130 766
140 6859
150 28249

Benchmark Code

let start = performance.now();

let network = new Network({
  inputs: 1000,
  outputs: 150
});

let end  = performance.now();

console.log(end - start);

Benchmark Results (Image) image

Source Code

let _ = require("./_");
let EventEmitter = require('eventemitter3');
let { performance } = require("perf_hooks");

Math.cantor = function(a, b) {
  a = parseInt(a); b = parseInt(b); // cast to integer
  return ((a + b) * (a + b + 1)) / 2 + b;
}

function Connection(options={}) {};
function Node(options={}) {};
function Network(options={}) {};

Connection = _.extend(Connection, EventEmitter);
Connection = _.extend(Connection, function(options={}) {
  this.id = options.id || Math.cantor(options.from, options.to);
});
Node = _.extend(Node, EventEmitter);
Node = _.extend(Node, function(options={}) {
  this.id = options.id;
});
Network = _.extend(Network, EventEmitter);
Network = _.extend(Network, function(options={}) {
  // constructor defaults
  options.inputs = options.inputs || 1;
  options.outputs = options.outputs || 1;

  // genome
  this.inputs = {};
  this.outputs = {};
  this.nodes = {};
  this.connections = {};
  this.NODES = 0;

  // new Network({ inputs, outputs })
  // create input nodes
  for (let i = 0; i < options.inputs; i++) {
    this.inputs[this.NODES] = this.nodes[this.NODES] = new Node({ id: this.NODES });
    ++this.NODES;
  }
  // create output nodes
  for (let o = 0; o < options.outputs; o++) {
    this.outputs[this.NODES] = this.nodes[this.NODES] = new Node({ id: this.NODES });
    ++this.NODES;
  }
  // connect input nodes to output nodes
  for (input in this.inputs) {
    for (output in this.outputs) {
      // connect input node to output node
      let connection = new Connection({ from: input, to: output });
      this.connections[connection.id] = connection;
    }
  }
});