(Updated) Testing the battery life impact of AppleScript widgets

Hey there!

I know many of you, myself included, have been interested in the battery life impact of running AppleScript Touch Bar widgets. Note that these are just my preliminary findings and may not be 100% accurate. I’ll update this post as I conduct more trials (considering that each takes 8+ hours).

TL;DR Running a lot of AppleScript widgets may reduce battery life by over 3 hours.

Setup

  • 2017 13-inch MacBook Pro with Touch Bar
  • 99% battery health (as reported by iStat Menus)
  • 3.5 GHz Intel Core i7
  • macOS High Sierra (10.13.4)
  • BetterTouchTool v2.536
  • AppleScript widget: GoldenChaos-BTT dynamic volume

Procedure

  1. Kill all non-system processes (except the iStat Menus daemons used for monitoring).
  2. Disable display sleeping, screensaver, and automatic brightness adjustment in System Preferences.
  3. Turn off Bluetooth and WiFi and disconnect any external accessories.
  4. Ensure Activity Monitor reports “Battery is Charged” in the Energy tab.
  5. Start BetterTouchTool and set up trial widget configurations.
  6. Disconnect from power and let sit for 8 hours. Note that AppleScript widgets are still run even when the Touch Bar display is off.
  7. Record actual elapsed time and final battery percentage.

Observations

Trial 0 (Control) — 0 runs/second

Configuration: No visible widgets (nothing executed)
Time elapsed: 8 hours, 10 minutes
End percentage: 63%

Trial 1 — 4.33 runs/second

Configuration: (2x, 1s interval) (1x, 0.5s interval), (1x, 3s interval) = 4.33 runs/second
Time elapsed: 8 hours, 19 minutes
End percentage: 55%

Trial 2 — 10 runs/second

Configuration: (10x, 1s interval) = 10 runs/second
Time elapsed: 9 hours, 22 minutes
End percentage: 36%

Calculations

Trial 0

100% - 63% = 37%
8 + 10/60 = 8.17 hrs
=> Total impact
37.0% / 8.17 hrs = 4.53 %/hr

Trial 1

100% - 55% = 45%
8 + 19/60 = 8.32 hrs
4.33 runs/sec
=> Total impact
45% / 8.32 hrs = 5.41 %/hr
=> Impact from AppleScript
5.41 %/hr - 4.53 %/hr = 0.88 %/hr

Trial 2

100% - 36% = 64%
9 + 22/60 = 9.37 hrs
=> Total impact
64% / 9.37 hrs = 6.83 %/hr
=> Impact from AppleScript
6.83 - 4.53 = 2.3 %/hr

Results

Trial 0 is the control which we use to determine the energy impact overhead from just running AppleScript widgets.

In Trial 1 there was a 0.88% per hour battery consumption overhead from the AppleScript widgets. In comparison, in Trial 2 there was a 2.3% per hour overhead.

The three trials indicates that the power consumption increases linearly relative to the number of widgets run per second. We can thus formulate a power consumption model as follows:

Power Consumption Model

Using WolframAlpha to perform a linear fit on the trials, we get the following for the power consumption model (power consumption as a function of the number of AppleScript runs per second).

p(x) = 4.486 + 0.231x

  • With an R^2 = 0.9967.
  • x is the number of AppleScript runs per second. (∀x ≥ 0).

Visualization

Using the model, we can now visualize the amount of battery life lost as a direct result of running AppleScript widgets. The reduction in battery life will be proportional to the total time the device is on battery power (the “expected capacity”). That is, if you play a video game and the battery only lasts 3 hours, then the total battery life reduction from BetterTouchTool will obviously be less.

This gives us the resulting graph:

Things to note:

  • Horizontal lines are in 10 minute intervals.
  • Extrapolated curves (using the model) are indicated with a dotted line.
  • For Trial 1 (4.33 runs/second), AppleScript reduces battery life by ~1 hour at Apple’s advertised MBP battery capacity of 10 hours.
  • For Trial 2 (10 runs/second), AppleScript reduces battery life by over 2 hours at Apple’s advertised MBP battery capacity of 10 hours.
  • The GoldenChaos-BTT defaults line uses a runs/second value obtained by auditing the AppleScript widgets in the primary app region and Control Strip areas. Some AppleScript widgets in that preset may be more or less CPU intensive than the volume widget used in the test.

Conclusion

For the best battery life avoid using AppleScript widgets to poll for events. Consider using a persistent service to push updates to BTT instead. Examples:

1 Like

Super interesting and useful. I would love to see how energy usage stacks up against some commonly used apps like Safari and iTunes.

I wonder if there would also be a way to optimize when BTT runs applescripts to make it more efficient. For example, does BTT run scripts even when the Touch Bar backlight is off?

Also, on a semi-related note, if there are any plugins in my preset that can be replaced with more efficient versions, would love to know so I can implement them.

Yes, that could be useful in quantifying the energy impact overhead from using AppleScript.

BetterTouchTool does run AppleScript widgets when the Touch Bar display is off (no backlight, since it’s an OLED strip).

The only real options are:

  1. Set widget intervals to 0 and use a standalone service instead to trigger refreshes. For example, you could pull out the service runner from my preset, configure the widget UUIDs, and use that. This option would obviously require non source-embedded dependencies, so you would need to make it an optional addition that would require people to configure.
  2. Use shell scripts (asynchronous execution) in combination with long-polling and a pool system. I experimented with this method before I discovered that BTT added support for pushing refreshes. The setup is pretty simple:
    • Run scripts at a reduced interval (e.g. every 3 seconds).
    • Each script that runs should use the Unix timestamp on initialization mod the pool size as its identifier.
    • Scripts wait until an event occurs (e.g. volume changes) on the Unix timestamp (mod the pool size) equal to the initialization identifier. Once that happens, return.
    • If no event occurs within pool size * interval * buffer, return.

Do you know if the scripts still run when the script widget is not visible?

They do not run when they're not visible!

Nice, didn't know the impact, but I'm paranoid enough to keep my script execution calls low anyway. Not keep anything heavy on the "global" bar or finding other ways to implement it. I'm curious how much the built-in widgets use -- clock, weather, etc...