Pros and Cons about using "custom" Functions vs the basic set of nodes

Hi Walter,
Every blockly node runs in its own sandbox (similar to the function nodes). This means it has only a little subset of the Node-RED API available. In fact, my server side code is a copy of the function node. Which is again a problem for me, since I have to keep it in sync with every change in the function node. But the blockly node can be installed on older Node-RED version, which means in run a new function node API in an older Node-RED version ...

I'm working on pull request to update unsafe-function node, hope will update it to 0.20 upcoming release. Already forked your node to perform the same :wink:

7 function nodes isn't a lot & the number people use may often depend on how well they know JavaScript. A function node can sometimes greatly simplify a complex flow making it easier to understand - but equally, it can sometimes do the reverse.

When you say "a lot", what are we talking about here? 100's of lines of code? 1000's?

When you get to very high levels of complexity, you need to be thinking about other issues too of course such as memory and CPU utilisation. Also you need to think about supporting all that code. Is it documented? Will you understand it in 6 months or more? Is there any common code that you could refactor into a library of it's own? Has some of the code reached a critical mass where it may no longer make sense in Node-RED and might be better in its own microservice?

In truth, unless your function code is 1000's or 10's of 1000's of lines long, you've probably not really hit any critical complexity as yet. However, once you hit a few 100 lines per node, probably time to start to think ahead about how to best organise it.

I have a very complex flow with many Function nodes and flow tabs with lots of stuff. It is running rock-solid on a Pi3 since long and never restarts or crashes. Memory consumption is stable, CPU utilization as well. Maybe the size of your flow file can give an indication? Mine is 348 kB, has 142 Function nodes (some might be possible to replace with std nodes) and the response is still very fast, triggering a light on/off from the dashboard turns it on/off "immediately"

My "live" system runs at a 616k file size for flows.json.

Current process size:

VmPeak: 238340 kB
VmSize: 229124 kB

Here is the count of all the nodes. As you can see, I'm currently down to "just" 77 function nodes :wink:

{
    "TOTAL": 997,
    "batch": 1,
    "bigtimer": 8,
    "catch": 8,
    "change": 86,
    "comment": 154,
    "darksky": 1,
    "darksky-credentials": 1,
    "debug": 146,
    "exec": 14,
    "file in": 5,
    "function": 77,
    "http in": 8,
    "http request": 14,
    "http response": 5,
    "inject": 85,
    "is online": 1,
    "join": 1,
    "json": 22,
    "later": 2,
    "link in": 11,
    "link out": 38,
    "mqtt in": 51,
    "mqtt out": 29,
    "mqtt-broker": 4,
    "openweathermap": 1,
    "ping": 3,
    "rbe": 4,
    "rfx-detector-in": 1,
    "rfx-doorbell-in": 1,
    "rfx-doorbell-out": 1,
    "rfx-lights-in": 2,
    "rfx-lights-out": 1,
    "rfx-meter": 2,
    "rfx-sensor": 2,
    "rfxtrx-port": 1,
    "rive": 1,
    "serial in": 3,
    "serial-port": 2,
    "smartplug-device": 1,
    "smartplug-in": 2,
    "smartplug-out": 1,
    "smooth": 4,
    "status": 7,
    "subflow": 28,
    "switch": 15,
    "tab": 13,
    "telegram bot": 3,
    "telegram command": 9,
    "telegram reply": 1,
    "telegram sender": 6,
    "template": 17,
    "trigger": 14,
    "ui_audio": 1,
    "ui_base": 1,
    "ui_chart": 6,
    "ui_group": 19,
    "ui_link": 2,
    "ui_switch": 1,
    "ui_tab": 10,
    "ui_template": 22,
    "ui_text": 7,
    "uibuilder": 2,
    "watch": 1,
    "websocket in": 2,
    "websocket out": 1,
    "websocket-listener": 2,
    "worldmap": 1,
    "wunderground": 1
}

And, yes, this is totally reliable with a couple of minor exceptions that are due to the Pi and updates, not Node-RED.

Thanks. Shall investigate.

W...T....H are all them doing!!!!!!!!!

Haha, well there's all the inputs from various hardware that gets standardised and send to MQTT. Then there are secondary flows that listen for the hardware MQTT topics and break the data out for specific purposes whether informational or controlling stuff. There's a lot of processing for the Telegram conversational and command interfaces, some web interface stuff, some warnings (processing sensor inputs and outputing warnings).

It is somewhat more complex than absolutely required because I decided early on that I wanted processing disaggregated so that it was much easier to swap out hardware. That has proved very useful over time. It has also allowed me to easily add new hardware, sensors, controls and new interfaces.

And then there are some test flows too. I use my live system to test out ideas over time. Though I'm gradually moving over to a new Pi3 (from my live Pi2).

And, of course, as this has happened over several years, there is some history in there that needs tidying which will happen as I migrate.

1 Like

Also not to forget, very good indeed, seems very, very well commented & debugged
:+1:

1 Like

BTW it may be intersting to see which nodes are most used.

I guess inject, debug, change, function

Here is a small contrib-node for the statistic: node-red-contrib-flow-statistics

My smart home on a RPi flow.json size 571KB

{
	"Total": 1205,
	"catch": 9,
	"change": 92,
	"comment": 61,
	"debug": 85,
	"delay": 13,
	"dropbox out": 1,
	"dropbox-config": 1,
	"dsm": 38,
	"e-mail": 1,
	"e-mail in": 1,
	"exec": 4,
	"file": 2,
	"flow-statistics": 1,
	"function": 60,
	"http in": 2,
	"http request": 5,
	"http response": 2,
	"hue-bridge": 1,
	"hue-light": 6,
	"inject": 198,
	"join": 1,
	"json": 27,
	"link in": 83,
	"link out": 74,
	"mqtt in": 36,
	"mqtt out": 44,
	"mqtt-broker": 1,
	"netatmo-config-node": 1,
	"netatmo-dashboard": 1,
	"persist in": 19,
	"persist out": 19,
	"persist-store": 2,
	"ping": 6,
	"profile": 9,
	"pushover": 2,
	"ramp-thermostat": 9,
	"rbe": 6,
	"rpi-ds18b20": 1,
	"schedex": 9,
	"status": 2,
	"subflow": 5,
	"subflow:12064036.6833f": 51,
	"subflow:b33c0f5.cd2e4f": 8,
	"subflow:b5804ad5.22a2d8": 14,
	"subflow:c72ea31a.28c6e": 4,
	"subflow:cd88b0fe.f7772": 8,
	"switch": 46,
	"tab": 11,
	"template": 37,
	"time-range-switch": 1,
	"trigger": 10,
	"ui_base": 1,
	"ui_chart": 18,
	"ui_gauge": 1,
	"ui_group": 14,
	"ui_slider": 3,
	"ui_switch": 11,
	"ui_tab": 7,
	"ui_template": 1,
	"ui_text": 23,
	"ui_text_input": 4,
	"zwave-controller": 1,
	"zwave-in": 1,
	"zwave-out": 1
}

Because I submitted the pull request to use "function node without vm module" in the node-red-nodegen project, I'm interested in the performance of the default function node. Today, I conducted simple experiments to measure the performance in each approach.

Compared to the default function node, "nodegen function without vm module" and unsafe function can dramatically reduce the execution time. I hope that "nodegen function without vm module" will be one of the general approaches in Node-RED community. :slight_smile:

  • Approaches

    • No filter
    • Default function node
    • Default switch node
    • nodegen function (original node generated from function node using node-red-nodegen v0.0.2)
    • nodegen function without vm module (original node which was generated from function node using new node template submitted in the pull request)
    • unsafe function (node-red-contrib-unsafe-function)
  • Flow to evaluate
    (1) Kick the flow using inject node and then output timestamp to debug node.
    (2) Create the array which contains 0 and 1 values (Lengths of the array are 16K, 32K, 64K and 128K)
    (3) Split the array using split node
    (4) Execute the filter code in each approach

    if (0 < msg.payload) {
        return [msg, null];
    } else {
        return [null, msg];
    }
    

    (5) Merge all messages using join node
    (6) Get and output timestamp when join node merged all messages

  • Environment

    • Node-RED v0.19.3
    • node-red-nodegen v0.0.2
    • Node.js v8.10.0
    • npm v3.5.2
    • OS: Ubuntu 18.4 (Bash on Windows 10 Pro)
    • Hardware: Surface Pro 2017 model (Intel Core i5 7300U CPU@2.60GHz, Memory 8GB)
2 Likes

@kazuhitoyokoi - could you provide your test flow incase someone else wants to test it on other devices.

My main takeaway from that is the Switch node needs some serious optimisation work. I'm surprised to see it perform so badly. I wonder if the persistence context work, which adds async behaviour, is causing this overhead.

2 Likes

or is there some cloning going on in there ?

Sure! I pasted my test flow as follows. I'm interested in the results on other devices. Especially, Raspberry Pi Zero.
As @knolleary mentioned, the current switch node has low performance. The result is different from the results which @Colin investigated in January.

[Test flow]

[{"id":"22b6f824.1d3d28","type":"debug","z":"96cb18ac.349558","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1150,"y":160,"wires":[]},{"id":"b6391290.93b68","type":"split","z":"96cb18ac.349558","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":510,"y":160,"wires":[["c2795061.c68ec"]]},{"id":"c2795061.c68ec","type":"join","z":"96cb18ac.349558","name":"","mode":"auto","build":"string","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":"false","timeout":"","count":"","reduceRight":false,"x":870,"y":160,"wires":[["1f02fec1.10f9a1"]]},{"id":"e589003.1b546","type":"debug","z":"96cb18ac.349558","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1150,"y":320,"wires":[]},{"id":"ee961a3f.b3c8d8","type":"function","z":"96cb18ac.349558","name":"function","func":"if (0 < msg.payload) {\n    return [msg, null];\n} else {\n    return [null, msg];\n}","outputs":2,"noerr":0,"x":700,"y":320,"wires":[["c0a23080.d5156"],["c0a23080.d5156"]]},{"id":"f3351b90.325488","type":"split","z":"96cb18ac.349558","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":510,"y":320,"wires":[["ee961a3f.b3c8d8"]]},{"id":"c0a23080.d5156","type":"join","z":"96cb18ac.349558","name":"","mode":"auto","build":"string","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":"false","timeout":"","count":"","reduceRight":false,"x":870,"y":320,"wires":[["1c8ec1a3.fd437e"]]},{"id":"9cfc6267.658ff","type":"switch","z":"96cb18ac.349558","name":"","property":"payload","propertyType":"msg","rules":[{"t":"gt","v":"0","vt":"num"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":690,"y":480,"wires":[["9ef5b0e9.e0794"],["9ef5b0e9.e0794"]]},{"id":"6f7ea158.72daa","type":"debug","z":"96cb18ac.349558","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1150,"y":480,"wires":[]},{"id":"9306e26b.bc3e3","type":"split","z":"96cb18ac.349558","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":510,"y":480,"wires":[["9cfc6267.658ff"]]},{"id":"9ef5b0e9.e0794","type":"join","z":"96cb18ac.349558","name":"","mode":"auto","build":"string","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":"false","timeout":"","count":"","reduceRight":false,"x":870,"y":480,"wires":[["795ab8fb.a76418"]]},{"id":"e0f7fccf.d3d1f","type":"debug","z":"96cb18ac.349558","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1150,"y":960,"wires":[]},{"id":"324eb40b.8ac1dc","type":"split","z":"96cb18ac.349558","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":510,"y":960,"wires":[["840c08dd.30c768"]]},{"id":"b6e70644.bf8818","type":"join","z":"96cb18ac.349558","name":"","mode":"auto","build":"string","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":"false","timeout":"","count":"","reduceRight":false,"x":870,"y":960,"wires":[["8bf2d19f.a3a7e"]]},{"id":"b751a475.ce1018","type":"debug","z":"96cb18ac.349558","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":370,"y":200,"wires":[]},{"id":"1f02fec1.10f9a1","type":"function","z":"96cb18ac.349558","name":"get time","func":"msg.payload = new Date().getTime();\nreturn msg;","outputs":1,"noerr":0,"x":1000,"y":160,"wires":[["22b6f824.1d3d28"]]},{"id":"1c8ec1a3.fd437e","type":"function","z":"96cb18ac.349558","name":"get time","func":"msg.payload = new Date().getTime();\nreturn msg;","outputs":1,"noerr":0,"x":1000,"y":320,"wires":[["e589003.1b546"]]},{"id":"795ab8fb.a76418","type":"function","z":"96cb18ac.349558","name":"get time","func":"msg.payload = new Date().getTime();\nreturn msg;","outputs":1,"noerr":0,"x":1000,"y":480,"wires":[["6f7ea158.72daa"]]},{"id":"8bf2d19f.a3a7e","type":"function","z":"96cb18ac.349558","name":"get time","func":"msg.payload = new Date().getTime();\nreturn msg;","outputs":1,"noerr":0,"x":1000,"y":960,"wires":[["e0f7fccf.d3d1f"]]},{"id":"843c40e8.02945","type":"function","z":"96cb18ac.349558","name":"create array","func":"msg.payload = [];\nfor (var i = 0; i < msg.topic; i++) {\n    msg.payload.push(0);\n    msg.payload.push(1);\n}\nreturn msg;","outputs":1,"noerr":0,"x":370,"y":160,"wires":[["b6391290.93b68"]]},{"id":"840c08dd.30c768","type":"unsafe-function","z":"96cb18ac.349558","name":"unsafe function","func":"if (0 < msg.payload) {\n    return [msg, null];\n} else {\n    return [null, msg];\n}","outputs":2,"noerr":0,"x":700,"y":960,"wires":[["b6e70644.bf8818"],["b6e70644.bf8818"]]},{"id":"acd21a99.d22b08","type":"debug","z":"96cb18ac.349558","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1150,"y":640,"wires":[]},{"id":"fd1f5b96.955378","type":"split","z":"96cb18ac.349558","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":510,"y":640,"wires":[["2739ed02.031772"]]},{"id":"308209d.70953f6","type":"join","z":"96cb18ac.349558","name":"","mode":"auto","build":"string","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":"false","timeout":"","count":"","reduceRight":false,"x":870,"y":640,"wires":[["2f576f8f.49ed9"]]},{"id":"2f576f8f.49ed9","type":"function","z":"96cb18ac.349558","name":"get time","func":"msg.payload = new Date().getTime();\nreturn msg;","outputs":1,"noerr":0,"x":1000,"y":640,"wires":[["acd21a99.d22b08"]]},{"id":"7253166b.0a6fb8","type":"debug","z":"96cb18ac.349558","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":1150,"y":800,"wires":[]},{"id":"caf294f8.7b0a58","type":"split","z":"96cb18ac.349558","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":510,"y":800,"wires":[["c7be1c7b.1db83"]]},{"id":"fb197dc6.94184","type":"join","z":"96cb18ac.349558","name":"","mode":"auto","build":"string","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":"false","timeout":"","count":"","reduceRight":false,"x":870,"y":800,"wires":[["a0178366.7c2df"]]},{"id":"a0178366.7c2df","type":"function","z":"96cb18ac.349558","name":"get time","func":"msg.payload = new Date().getTime();\nreturn msg;","outputs":1,"noerr":0,"x":1000,"y":800,"wires":[["7253166b.0a6fb8"]]},{"id":"2739ed02.031772","type":"nodegen-function","z":"96cb18ac.349558","name":"","x":690,"y":640,"wires":[["308209d.70953f6"],["308209d.70953f6"]]},{"id":"c7be1c7b.1db83","type":"nodegen-function-wovm","z":"96cb18ac.349558","name":"","x":690,"y":800,"wires":[["fb197dc6.94184"],["fb197dc6.94184"]]},{"id":"a0b93f5.871afc","type":"inject","z":"96cb18ac.349558","name":"","topic":"16384","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":120,"wires":[["843c40e8.02945","b751a475.ce1018"]]},{"id":"9d6db1fc.bc468","type":"inject","z":"96cb18ac.349558","name":"","topic":"32768","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":160,"wires":[["843c40e8.02945","b751a475.ce1018"]]},{"id":"a26945de.fe00a8","type":"inject","z":"96cb18ac.349558","name":"","topic":"65536","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":200,"wires":[["843c40e8.02945","b751a475.ce1018"]]},{"id":"e1d0f2c2.74f4","type":"inject","z":"96cb18ac.349558","name":"","topic":"131072","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":240,"wires":[["843c40e8.02945","b751a475.ce1018"]]},{"id":"df436b3f.88da08","type":"debug","z":"96cb18ac.349558","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":370,"y":360,"wires":[]},{"id":"935172d4.12d58","type":"function","z":"96cb18ac.349558","name":"create array","func":"msg.payload = [];\nfor (var i = 0; i < msg.topic; i++) {\n    msg.payload.push(0);\n    msg.payload.push(1);\n}\nreturn msg;","outputs":1,"noerr":0,"x":370,"y":320,"wires":[["f3351b90.325488"]]},{"id":"ff205763.2fdce8","type":"inject","z":"96cb18ac.349558","name":"","topic":"16384","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":280,"wires":[["935172d4.12d58","df436b3f.88da08"]]},{"id":"cbcd61bd.1f60e","type":"inject","z":"96cb18ac.349558","name":"","topic":"32768","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":320,"wires":[["935172d4.12d58","df436b3f.88da08"]]},{"id":"af555047.2279","type":"inject","z":"96cb18ac.349558","name":"","topic":"65536","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":360,"wires":[["935172d4.12d58","df436b3f.88da08"]]},{"id":"dc506e50.0dada","type":"inject","z":"96cb18ac.349558","name":"","topic":"131072","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":400,"wires":[["935172d4.12d58","df436b3f.88da08"]]},{"id":"5d5f9d9e.58cec4","type":"debug","z":"96cb18ac.349558","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":370,"y":520,"wires":[]},{"id":"e717f529.a293f8","type":"function","z":"96cb18ac.349558","name":"create array","func":"msg.payload = [];\nfor (var i = 0; i < msg.topic; i++) {\n    msg.payload.push(0);\n    msg.payload.push(1);\n}\nreturn msg;","outputs":1,"noerr":0,"x":370,"y":480,"wires":[["9306e26b.bc3e3"]]},{"id":"27fc8cb8.b3af14","type":"inject","z":"96cb18ac.349558","name":"","topic":"16384","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":440,"wires":[["e717f529.a293f8","5d5f9d9e.58cec4"]]},{"id":"17c5c232.a506fe","type":"inject","z":"96cb18ac.349558","name":"","topic":"32768","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":480,"wires":[["e717f529.a293f8","5d5f9d9e.58cec4"]]},{"id":"564ac31b.dc2fcc","type":"inject","z":"96cb18ac.349558","name":"","topic":"65536","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":520,"wires":[["e717f529.a293f8","5d5f9d9e.58cec4"]]},{"id":"53e70f40.30328","type":"inject","z":"96cb18ac.349558","name":"","topic":"131072","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":560,"wires":[["e717f529.a293f8","5d5f9d9e.58cec4"]]},{"id":"64aaf49c.ddb4dc","type":"debug","z":"96cb18ac.349558","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":370,"y":680,"wires":[]},{"id":"3b44c559.57b6ba","type":"function","z":"96cb18ac.349558","name":"create array","func":"msg.payload = [];\nfor (var i = 0; i < msg.topic; i++) {\n    msg.payload.push(0);\n    msg.payload.push(1);\n}\nreturn msg;","outputs":1,"noerr":0,"x":370,"y":640,"wires":[["fd1f5b96.955378"]]},{"id":"70dfc3ca.c841ec","type":"inject","z":"96cb18ac.349558","name":"","topic":"16384","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":600,"wires":[["3b44c559.57b6ba","64aaf49c.ddb4dc"]]},{"id":"c16f793c.9b4058","type":"inject","z":"96cb18ac.349558","name":"","topic":"32768","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":640,"wires":[["3b44c559.57b6ba","64aaf49c.ddb4dc"]]},{"id":"93705687.4237f8","type":"inject","z":"96cb18ac.349558","name":"","topic":"65536","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":680,"wires":[["3b44c559.57b6ba","64aaf49c.ddb4dc"]]},{"id":"5354db08.e19524","type":"inject","z":"96cb18ac.349558","name":"","topic":"131072","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":720,"wires":[["3b44c559.57b6ba","64aaf49c.ddb4dc"]]},{"id":"14e2fcad.603a13","type":"debug","z":"96cb18ac.349558","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":370,"y":840,"wires":[]},{"id":"eee3a9ea.1f4d98","type":"function","z":"96cb18ac.349558","name":"create array","func":"msg.payload = [];\nfor (var i = 0; i < msg.topic; i++) {\n    msg.payload.push(0);\n    msg.payload.push(1);\n}\nreturn msg;","outputs":1,"noerr":0,"x":370,"y":800,"wires":[["caf294f8.7b0a58"]]},{"id":"8b523560.689b68","type":"inject","z":"96cb18ac.349558","name":"","topic":"16384","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":760,"wires":[["eee3a9ea.1f4d98","14e2fcad.603a13"]]},{"id":"ade36a1f.feaa68","type":"inject","z":"96cb18ac.349558","name":"","topic":"32768","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":800,"wires":[["eee3a9ea.1f4d98","14e2fcad.603a13"]]},{"id":"7f7814c7.96c62c","type":"inject","z":"96cb18ac.349558","name":"","topic":"65536","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":840,"wires":[["eee3a9ea.1f4d98","14e2fcad.603a13"]]},{"id":"7a1522ac.4db17c","type":"inject","z":"96cb18ac.349558","name":"","topic":"131072","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":880,"wires":[["eee3a9ea.1f4d98","14e2fcad.603a13"]]},{"id":"23cd67c5.5ac488","type":"debug","z":"96cb18ac.349558","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":370,"y":1000,"wires":[]},{"id":"fa3e34e0.336788","type":"function","z":"96cb18ac.349558","name":"create array","func":"msg.payload = [];\nfor (var i = 0; i < msg.topic; i++) {\n    msg.payload.push(0);\n    msg.payload.push(1);\n}\nreturn msg;","outputs":1,"noerr":0,"x":370,"y":960,"wires":[["324eb40b.8ac1dc"]]},{"id":"e6d8a9e5.b6e088","type":"inject","z":"96cb18ac.349558","name":"","topic":"16384","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":920,"wires":[["fa3e34e0.336788","23cd67c5.5ac488"]]},{"id":"7749a10b.35a49","type":"inject","z":"96cb18ac.349558","name":"","topic":"32768","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":960,"wires":[["fa3e34e0.336788","23cd67c5.5ac488"]]},{"id":"ac7649b0.5dc7d8","type":"inject","z":"96cb18ac.349558","name":"","topic":"65536","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":1000,"wires":[["fa3e34e0.336788","23cd67c5.5ac488"]]},{"id":"1691b9c4.38e086","type":"inject","z":"96cb18ac.349558","name":"","topic":"131072","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":170,"y":1040,"wires":[["fa3e34e0.336788","23cd67c5.5ac488"]]},{"id":"a95d4b79.b5e398","type":"comment","z":"96cb18ac.349558","name":"No filter","info":"","x":690,"y":140,"wires":[]},{"id":"b1c00742.17d608","type":"comment","z":"96cb18ac.349558","name":"Filter using default function","info":"","x":710,"y":280,"wires":[]},{"id":"97874710.ff8d88","type":"comment","z":"96cb18ac.349558","name":"Filter using nodegen function","info":"","x":700,"y":600,"wires":[]},{"id":"ce9093d2.6435a","type":"comment","z":"96cb18ac.349558","name":"Filter using nodegen function without vm","info":"","x":700,"y":760,"wires":[]},{"id":"48f00ef5.70c19","type":"comment","z":"96cb18ac.349558","name":"Filter using unsafe function","info":"","x":690,"y":920,"wires":[]},{"id":"590a90b.45ff97","type":"comment","z":"96cb18ac.349558","name":"Filter using default switch","info":"","x":690,"y":440,"wires":[]}]

[Screenshot of test flow] *Red rectangle means the filters.

[How to create nodegen function from default function]

1 Like

Great work, thanks for doing this. Really useful.

1 Like

@kazuhitoyokoi - do you have a simple set of steps to create the nodegen fuction blocks? Or do I have to wade thru that info to create them?

The README.md in node-red-nodegen project has simple steps to create nodegen function nodes as follows.

## Installation
* sudo npm install -g node-red-nodegen

### Create original node from function node
* On Node-RED flow editor, save function node to library with file name (lower-case.js).
* node-red-nodegen ~/.node-red/lib/function/lower-case.js
* cd node-red-contrib-lower-case
* sudo npm link
* cd ~/.node-red
* npm link node-red-contrib-lower-case
* node-red
-> You can use lower-case node on Node-RED flow editor.

You can also create "function node without vm module" using the following steps.

## Installation
* git clone https://github.com/kazuhitoyokoi/node-red-nodegen.git
* cd node-red-nodegen
* git checkout master-functionwithoutvm
* npm install

### Create original node from function node
* On Node-RED flow editor, save function node to library with file name (lower-case.js).
* node bin/node-red-nodegen.js ~/.node-red/lib/function/lower-case.js --name lower-case-wovm
* cd node-red-contrib-lower-case-wovm
* sudo npm link
* cd ~/.node-red
* npm link node-red-contrib-lower-case-wovm
* node-red
-> You can use lower-case-wovm node on Node-RED flow editor.

In the future, Node-RED flow editor will be able to have nodegen UI. Currently there is the design note about the UI.

I've just pushed a fix to git that restores the performance of the Switch node:

Number of messages Function Time (ms) Switch Time (ms)
16384 1216 331
32768 2081 600
65536 4125 1124
131072 8282 2207

This fix only applies if the node doesn't try to access context.

I suspect a similar performance regression will have been introduced to the Change node - I'll sort that out next.

3 Likes

Thank you for the optimization. :slight_smile: I'll use the new version of Node-RED!