# Update one object in Global Context array

**URL:** <https://discourse.nodered.org/t/update-one-object-in-global-context-array/36790>\
**Category:** General\
**Created:** [1 December 2020 08:59 UTC](https://discourse.nodered.org/t/update-one-object-in-global-context-array/36790 "2020-12-01T08:59:41Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![cllp](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cllp/32/32923_2.png) [@cllp](https://discourse.nodered.org/u/cllp)\
**Post date:** [1 December 2020 08:59 UTC](https://discourse.nodered.org/t/update-one-object-in-global-context-array/36790/1 "2020-12-01T08:59:41Z")

</div>

Hi, I´m worikng with the global context to stora an array of devices. For a device´s incoming message I use the global.get and filter on the whole devicelist array to find the specific object (device). I´m updating some values on the device and then in order to save the object (device) in the global context array, I use the global.set on the whole array. I don´t think this way is really optimised for performance, and would like to get som e ideas of how to just update one object in an array in the global context. How would you do it?

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [1 December 2020 09:03 UTC](https://discourse.nodered.org/t/update-one-object-in-global-context-array/36790/2 "2020-12-01T09:03:50Z")

</div>

> [@cllp](#):
>
> I don´t think this way is really optimised for performance

Why don't you think this is optimised? In fact this is likely the fastest possible method. When you call `global.set` you are only storing the reference (not the whole array).

See [this](https://discourse.nodered.org/t/working-with-local-storage-for-context-flow-and-global-variables/36320/4) recent post

---

<div class="post-metadata">

**Author:** ![cllp](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cllp/32/32923_2.png) [@cllp](https://discourse.nodered.org/u/cllp)\
**Post date:** [1 December 2020 11:15 UTC](https://discourse.nodered.org/t/update-one-object-in-global-context-array/36790/3 "2020-12-01T11:15:24Z")

</div>

Well... The array contains about 1500 objects, which all is quite large. When I call global.get I assume I get a reference to all objects in the array. I use the devices = global.get ... .findIndex((obj =\> obj.DeviceId == deviceId)); in order to find the object in the array I´m looking for. Then I do some updates on the object: devices[objIndex].LatestFcntUp = latestFcntUp;

Then I go: global.set("Devices",devices); And I figure I save the whole array with all objects in the global context. The thing is that I do this several times every second and I´m worried that this is not optimal for performance. I just want to update and save one object at the time that is. But how do I ensure that with global.set() ?

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [1 December 2020 11:25 UTC](https://discourse.nodered.org/t/update-one-object-in-global-context-array/36790/4 "2020-12-01T11:25:49Z")

</div>

ok, so again, global.set only stores the reference so its not writing 1500 objects (unless you have persistent storage then it will write the whole shebang to file when it flushes to file every 30s)

If you insist on looking for an alternative then you can use `global.set("myobject.subobject",value)` **BUT** as Nick said in the post I linked to _"If I had to guess, I'd say getting the whole object, then addressing the sub property directly then writing the whole object back would be mildly more efficient as you can let native JavaScript do the property lookup in the object, rather than have our code parse your property expression and dig into the object"_

If you REALLY want an improvement - use a lookup object instead of searching an array.

e.g.

```auto
var devices = global.get("Devices") || {};
var device = devices[deviceId]; //Lookup a key instead of searching array
if(device) {
  device.LatestFcntUp = latestFcntUp;
} else {
  devices[deviceId] = {LatestFcntUp : latestFcntUp};
}
global.set("Devices", devices )

```

HOWEVER that said, remember, [premature optimisation is the root of all evil](https://www.google.com/search?q=premature+optimisation+is+the+root+of+all+evil) - are you actually seeing an issue?

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [1 December 2020 11:31 UTC](https://discourse.nodered.org/t/update-one-object-in-global-context-array/36790/5 "2020-12-01T11:31:47Z")

</div>

> [@cllp](#):
>
> When I call global.get I assume I get a reference to all objects in the array.

No, when you call global.get you a reference to one object, the array. The array then contains the references to the contained objects. When you use global.set, referencing the whole array, then again it just stores the reference to that array.  
If, however, you are using persistent context, for example to the file system, then it occasionally flushes the whole structure out to disc. The maximum rate that that will happen at can be set as required.

---

<div class="post-metadata">

**Author:** ![E1cid](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/e1cid/32/77971_2.png) [@E1cid](https://discourse.nodered.org/u/E1cid)\
**Post date:** [1 December 2020 11:43 UTC](https://discourse.nodered.org/t/update-one-object-in-global-context-array/36790/6 "2020-12-01T11:43:44Z")

</div>

I ran tests a few months back on an array with 10000 elements, It is faster to call the complete global object ie.  
`global.get("object")["element"] is faster then global.get("object.element")` The bigger the object the slower it was.

So i would think `global.set("object.element", value)` would be less eficient.

---

<div class="post-metadata">

**Author:** ![cllp](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cllp/32/32923_2.png) [@cllp](https://discourse.nodered.org/u/cllp)\
**Post date:** [1 December 2020 14:24 UTC](https://discourse.nodered.org/t/update-one-object-in-global-context-array/36790/7 "2020-12-01T14:24:25Z")

</div>

First, many thanks for great input. I don´t insist an alternative if I´m doing it ok! Just wanna optimize as best as I can. About the optimizaton: "use a lookup object instead of searching an array". How do I do that with objects with peroperties like DeviceId, DevEui etc. I don´t see how this works: `var device = devices[deviceId]; //Lookup a key instead of searching array.`

Furthermore, I have enabled the "Persist contexts to disk" for my instance, this is because I can´t risk to loose the global context array. What are the proos and cons here. I guess that having it in memory will be much faster, or is it just the writing to disk every 30 sec that makes it slower? I´m using the global context as a cache at this point, to avoid roundtrips to the DB. Maybe some cache service DB or something would be a better way to do it (e.g. Redis)? Suggestions?

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [1 December 2020 14:47 UTC](https://discourse.nodered.org/t/update-one-object-in-global-context-array/36790/8 "2020-12-01T14:47:45Z")

</div>

> [@cllp](#):
>
> I don´t see how this works: `var device = devices[deviceId]; //Lookup a key instead of searching array.`

Essentially, this is the same as object assignment.

consider this...

```auto
var myObject = {};
myObject.a_new_property = 123

```

is the same as

```auto
var myObject = {};
myObject["a_new_property"] = 123

```

is the same as

```auto
var myObject = {};
var propName = "a_new_property";
myObject[propName] = 123

```

so you can also access the sub property like this...

```auto
var the_value = myObject["a_new_property"]; //123

```

or like this...

```auto
var device = devices[deviceId]; //no array search here - just a lookup

```

where `devices` is an object with devices key'd by name  
where `deviceId` is a string with the name of the device that was assigned

* * *

Here is a demo...

[https://repl.it/join/glljpnpb-stephenmclaughl](https://repl.it/join/glljpnpb-stephenmclaughl)

... this is the final line of the repl.it in case you dont open it...  
`Look up is 52.17971960357747 times faster than searching an array of 1500 (depending on the element you ask for)` (note this changes for each execution but usually it is ~50x faster)

---

<div class="post-metadata">

**Author:** ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)\
**Post date:** [1 December 2020 16:27 UTC](https://discourse.nodered.org/t/update-one-object-in-global-context-array/36790/9 "2020-12-01T16:27:53Z")

</div>

> [@cllp](#):
>
> I guess that having it in memory will be much faster, or is it just the writing to disk every 30 sec that makes it slower?

It isn't any slower, the context you use is in memory exactly as normal, you just have the extra overhead of writing it to disk at whatever rate you specify, and the actual write will take place in a different process (I think) as the OS will cache it.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [1 December 2020 21:00 UTC](https://discourse.nodered.org/t/update-one-object-in-global-context-array/36790/10 "2020-12-01T21:00:23Z")

</div>

If you really do find that you need to optimise things, you are probably looking at using a database engine rather than a Node-RED variable.

As for having to search through arrays all the time, personally I always err to using Objects rather than arrays given that it is easy to get an array from an Object but not the other way around. With an object, you can simply do `myObj.key` or `myObj[varThatHoldsKey]`, no searching/filtering/looping required.

If you need the array from the object then `Object.values(myObj)` does the trick.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [30 January 2021 21:00 UTC](https://discourse.nodered.org/t/update-one-object-in-global-context-array/36790/11 "2021-01-30T21:00:42Z")

</div>

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.
