Cloud-Automation / node-modbus

Modbus TCP Client/Server implementation for Node.JS
471 stars 175 forks source link

Performance tweaks #63

Closed psorowka closed 7 years ago

psorowka commented 7 years ago

While analyzing a memory leak (in our code) we learned that this lib had two major optimization potentials, especially regarding the reqFifo. This Pull Request solves both of these (details below) by replacing the Promise library Q with its more performant counterpart bluebird and completely removes the Put dependency (which hasn't been touched for the last 5 years anyway).


Details:

we had a situation where requests where queueing in huge amounts leading to an out-of-memory error. While the fact that the requests where queuing is our fault, the memory usage was much higher than we thought it should be. We therefore created the following minimal test (against a locally running mock modbus server):

const modbus = require('jsmodbus')
const v8 = require('v8')

const client = modbus.client.tcp.complete({
        'host'              : 'localhost',
        'port'              : 8888,
})

client.connect()

client.on('connect', function () {
   for(let i=1; i < 1e5; i++)
     client.readCoils(0, 13)

   console.log('Heap:', Math.floor(v8.getHeapStatistics().used_heap_size / 1e6), 'MB')
})

the result:

# ORIGINAL MEMORY USAGE
$ node index.js 
Heap: 221 MB

after replacing Q with bluebird (only in readCoils for this test)

# MEMORY USAGE WITH BLUEBIRD INSTEAD OF Q
$ node index.js 
Heap: 109 MB

after getting rid of Put in favor of pure Buffer (also only in readCoils for this test)

# MEMORY USAGE WITH BLUEBIRD + Buffer INSTEAD OF Put
$ node index.js
Heap: 41 MB

after consequently updating the whole lib with these new findings (=> the current PR), it went even further down:

# MEMORY USAGE WITH COMPLETE REFACTORING (current PR)
$ node index.js
Heap: 35 MB
stefanpoeter commented 7 years ago

Great work, again! Nothing more to add. Thanks!

psorowka commented 7 years ago

Cool, thanks for the quick response!

stefanpoeter commented 7 years ago

Hey @psorowka,

i made you a collaborator for this repository, so you can create branches in this repository for pull requests next time.