It is currently June 17th, 2024, 11:33 pm

Battery usage optimization

Get help with creating, editing & fixing problems with skins
User avatar
creewick
Posts: 38
Joined: March 4th, 2022, 2:43 pm
Location: Almaty, Kazakhstan

Battery usage optimization

Post by creewick »

Hello! I'm working on a skin suite and recently I've got a review, that the suite drains a lot of battery

I've already tried to optimize it's CPU usage. To do so, I've reduced count of skin's updates by using DefaultUpdateDivider=-1
Also, I've used Windows' Performance Monitor to check the CPU usage graph

So, the questions are:
Does the CPU usage correlates with the battery usage?
What else can I do to reduce battery usage?
Is there a similar instrument like Performance Monitor to check or predict battery usage, in case I don't have a Windows laptop to test it?
User avatar
CyberTheWorm
Posts: 859
Joined: August 22nd, 2016, 11:32 pm
Location: Surrey, B.C., Canada

Re: Battery usage optimization

Post by CyberTheWorm »

This is hard because computers are not the same.
High CPU, GPU and mechanical drive access will the battery drain more, also if the laptop has an old battery. Batteries only have a limited life too.
The only source of knowledge is experience. Albert Einstein
Deviant Art Page
User avatar
Active Colors
Moderator
Posts: 1257
Joined: February 16th, 2012, 3:32 am
Location: Berlin, Germany

Re: Battery usage optimization

Post by Active Colors »

Using DefaultUpdateDivider=-1 is not enough sometimes depending on the complexity of your skin/suit.

I have pondered around your Monterey skin suit and found out that some of your skins are well optimized and some are not.


For example, the "Calendar (medium size)" is well optimized:
• it has Update=5000 — good
• it has DefaultUpdateDivider=-1 — great
• it has ONLY ONE updated element which is [MeasureDay] checking what day it is today ONCE EVERY 5 SECONDS — excellent

On the other hand, the "ActivityMonitor (medium size)" is badly optimized:
• Update=100 — bad
• Every meter (except base/background) has UpdateDivider=1 which means they are updated 10 times per second — awful
• Every measure has UpdateDivider=1 which again means they are updated 10 times per second — horrible

Hence, the Calendar skin will be easy on laptops' battery, however, the ActivityMonitor will be hard.




What you can do to optimize:


1. Make meters to update only when necessary.
  • You certainly do not need to have every meter to be updated 10 times per second. For instance, for me the disk and the net measure are not changing frequently, especially when I am not downloading/uploading from the internet and reading/writing big chunks of data. Then why would I need them be updated 10 times per second?

    Solution:
    Disable updating of all the meters and make relevant measures to update those meters. In the case of ActivityMonitor, in the [CPUMeasure] you can add OnChangeAction=[!UpdateMeter MeterMeter1][!Redraw]. Same applies to every other measure in this skin and other skins too. Now the meters are updated only when the values are actually updated, instead of updating shallowly.

2. Make child measures to update only when necessary.
  • In the same vein as the meters, but applied to "child" measures.

    Solution:
    Disable your child measures to be updated. For example, in the ActivityMonitor you have a "parent" measure [CPUMonitor] and a "child" measure [CPUMeasure]. Because [CPUMeasure] is dependent on [CPUMonitor], you don't need to have [CPUMeasure] to be updated by itself 10 times per second. Instead, make the parent [CPUMonitor] to update [CPUMeasure] when the main value is actually changing. As in the previous solution, you can do the following: disable [CPUMeasure] to be updated and add to [CPUMonitor] OnChangeAction=[!UpdateMeasure CPUMeasure][!Redraw]. Do the same for other parent-child measures.


    Combining the sections 1 and 2 you will have the following optimization:

    Code: Select all

    [CPUMonitor]
    UpdateDivider=1
    OnChangeAction=[!UpdateMeasure CPUMeasure][!Redraw]
    
    [CPUMeasure]
    UpdateDivider=-1
    OnChangeAction=[!UpdateMeter MeterMeter1][!Redraw]
    
    [MeterMeter1]
    UpdateDivider=-1
    Use the same approach for other places.

3. Reading system data 10 times within a second is a bad idea.
  • In the case of ActivityMonitor, it reads system data 10 times per second. Since you have 4 measures in the ActivityMonitor it makes total 40 calls to the system per second. This is enough to drain a battery. Besides ActivityMonitor you have other similar skins and if a user is running several skins like that then the battery will be draining even faster.

    Solution:
    Let people decide whether they want to have animations. You can add a setting which will let users decide whether to have animations or not. You can also add some little warning about the pros and cons of this setting. I am sure not everyone needs the animations. Disable animations => Update=1000; enable animation => Update=100.

    Expanded solution:
    Make your skins see what is the current power supply. You can add a setting to let users choose whether they want to disable animations when a battery is discharging and enable when a battery is charging. If battery is discharging => Update=1000; if battery is charging => Update=100.

4. If you want to use animations, use ActionTimer.
  • Generally speaking, reading some system data 10 times per second is not only bad performance wise, but also, in almost all cases, it is useless for a regular user.

    In my opinion, having 1 call per second to read CPU/RAM is way more than enough to build elaborate reports and have a better picture of a system performance. Having Update=100 makes it pleasant for eyes to see the smooth animations, but it comes with the performance drawbacks. It is worthy to invest the effort in ActionTimer to make animations rather than leaving your skins to read every system data 10 times per second. Fortunately, there are already some skins, examples, and forum discussions dedicated to making animations using ActionTimer.

    By using ActionTimer you can have Update=1000, update measures once per 1 second and also animate the value change in your bars. Somebody who is better than me in ActionTimer might correct me, but if you need to animate meters more than once per 1 second then it is not a good idea to fire ActionTimer that fast.
User avatar
creewick
Posts: 38
Joined: March 4th, 2022, 2:43 pm
Location: Almaty, Kazakhstan

Re: Battery usage optimization

Post by creewick »

Wow, thank you so much for the detailed review
I guessed there may be some issues with Activity Monitor skin, but I thought it's just like having another clock on screen.
I didn't thought it was that bad
Active Colors wrote: April 10th, 2022, 4:06 pm Make meters to update only when necessary.
Oh, I did so on Calendar, but kinda forgot to share same practice to other skins :???:
Active Colors wrote: April 10th, 2022, 4:06 pm Add update profiles for animations.
...
Make your skins see what is the current power supply
That's a good point. I guess, charging status should be availiable as global variable. I'll try to use it :thumbup:
Active Colors wrote: April 10th, 2022, 4:06 pm Consider ActionTimer or UniversalTransitions.
I've never heard about these plugins/scripts before. I guess it's just the time to get know them

Thank you for your time reviewing the suite :bow:
I'm trying to summarize all you'd said in a checklist.. so, if I get this right, it's better to:

- to redraw meters less frequently
- to have less measures
- to update measures less frequently
- while using DefaultUpdateDivider=-1, to use UpdateMeasure, UpdateMeter to reduce updates/redraws
- to provide some performance settings, so each user can decide for themself
- to animate using plugins instead of more frequent Update cycles
User avatar
Active Colors
Moderator
Posts: 1257
Joined: February 16th, 2012, 3:32 am
Location: Berlin, Germany

Re: Battery usage optimization

Post by Active Colors »

creewick wrote: April 10th, 2022, 5:06 pm
- to redraw meters less frequently
- to have less measures
- to update measures less frequently
- while using DefaultUpdateDivider=-1, to use UpdateMeasure, UpdateMeter to reduce updates/redraws
- to provide some performance settings, so each user can decide for themself
- to animate using plugins instead of more frequent Update cycles
Looks like a good checklist to me. Redrawing meters is the most pricy operation for the performance, so yeah, I would say it should be used visely. If you read from/write to system not faster than once a second you are fine as well, given that you do really need to read/write once a second.