Green Code and birches. Basic principles of green code in development

Hello. My name is Stas, at Domclick I oversee the development of back office services for mortgage lending at Sberbank.

Recently, in all sorts of reports and podcasts, I have often come across the term “Green Code”. Having rummaged on the Internet and studied this topic, it became clear that this term describes a set of techniques in the development and design of applications that can reduce the power consumption of the equipment on which this code is executed.

More or less this question is usually puzzled by developers of mobile applications, mainly because the device on which their code will be executed has a limited battery capacity.

The topic has become quite “hype”, and I decided to figure out how exactly the principles of “green” can be reflected in WEB-development.

Basic principles of writing “green code”

After reading a lot of reports and articles on this topic, I would highlight the following aspects of application development that affect power consumption:

1) Simplification and optimization of algorithms

As mentioned above, the execution of the code should lead to minimal energy consumption. The optimized code will execute faster and, therefore, will require less processing and equipment cooling costs.

Let’s try to calculate the difference in energy consumption for the execution of a specific operation in the code – the classic sorting of a list. I will deliberately exaggerate the situation in the given example in order to show the difference in more contrast.

Let’s take a bubble sort. This is probably one of the most sub-optimal ways. Very suitable for us. Let’s calculate the sorting of the list and see how it affected the power consumption of the MacBook. First, let’s simulate the data array and the bubble sort logic itself:

from random import randint



def bubble(array):

    for i in range(productNumber-1):

        for j in range(productNumber-i-1):

            if array[j] > array[j+1]:

                buff = array[j]

                array[j] = array[j+1]

                array[j+1] = buff



productNumber = 60000

products = []

for i in range(productNumber):

    products.append(randint(1, 1000))



bubble(products)

print(products)

To measure the impact of code execution on energy consumption, I used the iStat Menus 6 monitoring system (https://bjango.com/mac/istatmenus/). I connected my MacBook to the network, closed all third-party applications, waited for a certain time to charge the battery, and started sorting:

Energy consumption graph when performing bubble sort:

A pronounced jump in power consumption with a duration of 305 seconds is visible. It was caused by the execution of our non-optimal request. Additional spent energy in 5 minutes (305 seconds):

P = (W2 – W1) × 305 = (17,29 [мощность при выполнении скрипта] – 2,9 [мощность в состоянии покоя]) × 305 = 14,39 × 305 = 4389 Дж = 0,0012 кВт*ч

Now let’s say that this code accidentally lands on an industrial product server (let’s assume that the additional power consumption on the server will be the same as on my MacBook, and the dependence is directly proportional) and began to be executed with a frequency of 1 every 10 seconds. Then we will receive additional energy consumption per year:

365 дней × 24 часа × 3600 с/10 × 0,0012 кВт*ч = 3 784,32 кВт*ч

Suppose that the data center hosting the server receives power from a boiler room that uses birch wood as fuel. When burning 1 m3 birch wood is allocated 1900 kW * h / m3 energy. Of course, the efficiency of the boiler room is not 100%, and if we take it as 75%, then we get:

(3 784,32 / 1900) / 0,75 = 2,66 м3

If we take a tree as a regular cylinder, the volume of which is

V = Pi × R2 × H

where R is the radius of the tree trunk, let’s take it as 0.12 meters (average value),
H is the height of the tree trunk, let’s take it as 3 meters (average value).

then we get:

V = 3,14 × 0,0144 × 3 = 0,14 м3

This means that in one cubic meter of wood there will be 1 / 0,14 = 7,14 бревна

To provide energy for our script, we need a year 2,66 м3 × 7,14 = 19 берез

For comparison, I performed the same sort using the standard Python sorting method (.sort()).

Power consumption graph when doing standard sorting in Python:

Applying the same calculation logic (the peak duration was 10 sec), we get:

P = (W2 – W1) × 10 сек = (3,51 [мощность при выполнении скрипта] – 2,9 [мощность в состоянии покоя]) × 10 сек = 6,1 Дж = 0,0000016 кВт*ч

We will receive per year (provided that the operation is performed once every 10 seconds)

365 дней × 24 часа × 3600 с/10 × 0,0000016 кВт*ч = 5,05 кВт*ч

Or:

5,05 / 1900 / 0,75 × 7,14 = 0,025 бревна березы.

Of course, this example has a lot of assumptions, and bubble sort is rarely done. But the resulting numbers seemed interesting to me

2) Use the event driven model of the application wherever possible


The point is that most processors support multiple “states” of power consumption. In the event that the kernel is not busy with any calculations, the operating system puts it into a “sleep” state, in which the processor consumes much less power.

Spectrum of states (energy optimization):

You can read more about this. here

Quite often, there is a situation where some application logic must be executed when a certain event occurs. And to find out that this event has occurred, the service interested in receiving this information often periodically polls the service that stores the fact that this event has been completed. By timer. Moreover, the overwhelming majority of requests receive a negative answer, that is, 99% of requests, in fact, are not needed.

It would be correct to broadcast the corresponding event to the queue and read the fact of its occurrence to all interested services.

Spectrum of states (energy optimization):

Another example is the interaction of front-end and back-end application components. If the front needs to change its state depending on the data in the database, sometimes requests are periodically sent to the backend, creating unnecessary additional load. Although it is possible to inform the front about a change in the state of the necessary data through the socket server.

While sockets can be mistaken as well, here’s an example of “bad” code:

while(true)
{
        // Read data
        result = recv(serverSocket, buffer, bufferLen, 0);

        // Handle data  
        if(result != 0)
        {
                HandleData(buffer);
        }

        // Sleep and repeat
        Sleep(1000);
}

It can be seen that even if no data arrived at the socket, the code will still be executed every 1000 seconds, wasting precious energy.

The same thing can be written in a slightly different way, and less energy will be spent:

WSANETWORKEVENTS NetworkEvents;
WSAEVENT wsaSocketEvent;
wsaSocketEvent = WSACreateEvent();
WSAEventSelect(serverSocket, 
wsaSocketEvent, FD_READ|FD_CLOSE);
while(true)
{
    // Wait until data will be available in 
    the socket
    WaitForSingleObject(wsaSocketEve
    nt, INFINITE);
    // Read data
    result = recv(serverSocket, buffer, 
    bufferLen, 0);
    // Handle data 
    if(result != 0)
    {
        HandleData(buffer);
    }
} 

3) UI / UX: The user interface should not show “extra” data

If the data is still used, but rarely, then it is better not to display it by default, but to show it only by clicking the “Show detailed information” button.

A simple example illustrating this principle: displaying lists of data objects (requests, users, outlets, warehouses, offices), provided that the scenario for using the form still involves finding the desired object.

An example of a bad interface:

The page displays a huge list of tasks (divided into “pages”), but the user will still search for a specific client (according to certain logic in his head) in the search bar at the top. Why waste resources getting a to-do list?

The same scenario, implemented differently:

Example of a “green” interface:

The client selection logic has been moved to the system; by default, unnecessary data is not requested “out of habit”. This option, in addition to environmentalists, and cybersecurity will be fiercely applauded.

4) Refactoring

Refactoring is almost always useful. But in this context, it is needed for one simple purpose: to throw out unnecessary (garbage) code or to simplify the existing one to reduce power consumption.

Many applications that have been developing for more than three years accumulate hundreds of lines of unused or unpredictably working code left over from previously implemented (and possibly already cut) functions. Sometimes this code is even executed, but the result of its work is not required.

Periodic auditing and refactoring will reduce the amount of such code, although it probably won’t get rid of it completely.

For example, regularly refactoring one of our services (within the technical quota of working hours), we found this:

Refactoring example:

crm_deal_id – identifier of the mortgage transaction in the old system. Now it is no longer needed, but the code still contains a check for its receipt and an additional function call delete_deal_chat_telephonywhich performs a bunch of other actions.

All of this can be removed without losing functionality.

5) Use low-level programming languages ​​for high-load applications

Obviously, in most cases, applications written in low-level languages ​​are more energy efficient. It makes sense to rewrite a loaded service in Python (if it performs a simple operation) in C / C +. It will be faster and greener.

True, often we do not have the necessary knowledge to write logic in such languages.

6) Group I / O operations

Storage systems, like processors, also have different power states.
In “sleep” mode, much less energy is consumed than in an operating “warm” state. This is especially true for storage systems / hard drives.

If the application can group the data written to the disk and access the disk not constantly, but at certain periods of time, then it will be more energy efficient, because during the period of “idle” the operating system will send the disk to “hibernation”.

7) Using less power-hungry storage systems for logs

It is good practice to use “hot” and “cold” storage. For example, it makes sense to store logs for the last week in the indexed form of “hot” cooking, since the probability of accessing them will be quite high. Longer logs can be stored in cheaper and less power-hungry storage systems.

How about on an industrial scale?

Above, we covered the basic techniques for working with code to ensure its energy efficiency. But even following most of these rules will yield very modest savings that will be difficult to visualize. Of course, if the product does not sort the lists using the bubble method

The purposeful development of functionality for the implementation of electronic document management will give a much greater effect.

One of the activities of the Domclick teams is to optimize and simplify the process of obtaining a mortgage. And in this mortgage process, at the final stage, a lot of documents are prepared on paper. And in several copies. One copy for the seller, one for the buyer, one for the bank file.

I am pleased to know that Domclick is spending a lot of effort to eliminate this vicious practice and to transfer the entire document flow to electronic format. This year, a significant part of mortgage transactions has already been fully digitized (only one paper was printed: an application for the issuance of a UKEP, an enhanced cryptographic electronic signature). All other documents were signed by this UKEP and no paper was spent on them.

This initiative has already saved over 67,491,108 sheets of paper. In birches, there are about 23,000 trees!

Protect the environment!

Links for those interested:

  1. Green IT – available data and guidelines for reducing energy consumption in IT Systems / Ardito L .; Morisio M… – In: SUSTAINABLE COMPUTING. – ISSN 2210-5379. – STAMPA
  2. Understanding Green Software Development: A conceptual Framework / Luca Ardito, Giuseppe Procaccianti, Marco Torchiano, Antonio Vetro
  3. Green SW Engineering: Ideas for including Energy Efficiency into your Softwar Projects / Gerald Kaefer

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *