Code Size vs Code Speed

Things I have found from webCoRE, NST and other development

  • in Groovy, specifying types (Integer, Boolean, Map, List, Double) etc vs. def does improve execution of groovy code

    • this can avoid a lot of box, unbox code, and type conversions. -> smaller code

      • this also means for Map references, you need this: (Boolean)rtD.myBoolean, or (Integer)rtD.myInteger, etc
      • remember HE has to have code in memory to run, so smaller code == less memory needed
    • for small apps, probably not worth the effort, but if you have more than 200 lines of code in a groovy script, you should be doing this. (app or device)

  • use these types or void properly for methods that return values (or do not)

  • set large Maps, List, @Field static to null when you are done with them. Give the java GC a break (and HE Linux OS)

  • Avoid state, and atomicState as much as you can. These are expensive and use the db in HE

    • related to this is when you use them smaller, and less accesses is better.
    • note that think of settings, getDataValue, attributes etc as state. Treat them the same - less is more.
    • the database is a shared resource, so your garbage becomes everyone's garbage.
  • An alternative many times is @Field static ....

    • I find for state, folks have a few different use cases

      • you need to store something for a later run (but it does not matter if this persists across a reboot)

        • @Field static is good for this. When you don't need it any more set the @Field static variable to null
      • you need to store something that has to persist (across executions and reboots)

        • so this should be in state/atomicState, but you may still be able to cache with @Field static and write back changes to state/atomicState
      • you need shared state across multiple children (think shared memory)

        • again @Field static can do this with above view.
    • For me this is where SmartThings in the current (and perhaps new architecture) mis-understand the use cases for state and persistence.

      • this is why their current architecture is so expensive, and their new architecture with micro-services is going to end up relying on a db for all state again - especially when sharing is required.
  • If your groovy code can get multiple events / threads operating, there are many better and faster ways to synchronize/semaphore these threads than atomicState. This is a larger discussion, but if this happens a lot, try to avoid atomicState.

    • Typically thread synchronization does not require across reboot persistence (ie use @Field static with a semaphore array / hash).
  • logging is your friend, until it is not.

    • use it to debug, monitor, but quiet it down once stable - less is more.
      • auto shutoff is a polite feature.
      • it is also more polite for users to not see a bunch of logs
  • in device handlers, don't set isStateChange to true (in sendEvent, et al). just leave it alone and let HE do the right thing. Setting it to true further garbages up the db, etc.

  • if you schedule things, you have choices (depending on your need)

    • runIn does a one time schedule (so you repeatedly keep scheduling things)
    • schedule creates a schedule once and it just runs
      • it also works better across reboots or other exceptions - it is still scheduled.

I think @chuck.schwer is working on things to make responsiveness better, hopefully these will come out soon.

10 Likes