python get time performance

An interesting question that may come into ones mind is what is the effect of such a code on our app performance:

datetime.now()

This is a common line of code that probably can be found in almost every program in every language out there. We will try and answer this question in a few steps that take us to the kernel (or not ) using phrases such as system calls context switches and back to our simple line of code that just wanted to know what is the current time.

Who keeps track of the time and where is it stored?

On the motherboard, there is a microchip (Real-time clock) for this purpose. The chip uses crystal quarts that vibrate, the count of the vibrations is how the chip can tell the time. In addition, it has a small battery so even when your computer is off it can still vibrate and count the time. here is a cool post explaining the logic behind it. When the computer starts the operating system gains access to the memory in the Real-time clock and sets its date and time. From now “time interrupts” will maintain the time while the os is running (kernel clock). Every once in a while it will compare its time to the RTC time and date and see that’s it accurate. If you are running Linux just fire up your terminal and type

timedatectl
 Local time: Thu 2017-09-21 16:08:56 CEST
			     Universal time: Thu 2017-09-21 14:08:56 UTC
				   RTC time: Thu 2017-09-21 14:08:56
				  Time zone: Europe/Warsaw (CEST, +0200)
		  System clock synchronized: yes
	   systemd-timesyncd.service active: yes
			    RTC in local TZ: no

If an Internet connection is provided, the systemd-timesyncd service will automatically synchronize the local system clock with a remote Network Time Protocol server and the systemd-timedated service will make sure the new system clock is synchronized with the hardware clock (RTC) immediately.

*from man pages..

What are System calls?

python get time performance
Photo by Markus Spiske on Pexels.com

A system call is a way we can interact with the kernel of the OS. This allows user code to request services from the OS and it’s the only point we can reach out to the kernel when we need resources. Basically, the flow is once a program initiates a system call with the correct arguments. The call causes an exception and the processor jumps into a new address to handle the exception. This instruction will first save the process state (Context Switch) then call the actual function in the kernel that handles that system call that was requested, once It finishes it will restore the invoking process state and return the control to the user program. As you can guess this comes with a performance hit of additional cost switching between user space to kernel space and back.

Switching from one process to another requires a certain amount of time for doing the administration – saving and loading registers and memory maps, updating various tables and lists, etc. What is actually involved in a context switch depends on the architectures, operating systems, and the number of resources shared (threads that belong to the same process share many resources whether compared to unrelated non-cooperating processes. For example, in the Linux kernel, context switching involves switching registers, stack pointer (it’s typical stack-pointer register), program counter, flushing the translation lookaside buffer (TLB) and loading the page table of the next process to run (unless the old process shares the memory with the new).[2][3] Furthermore, analogous context switching happens between user threads, notably green threads, and is often very lightweight, saving and restoring minimal context. In extreme cases, such as switching between goroutines in Go, a context switch is equivalent to a coroutine yield, which is only marginally more expensive than a subroutine call.

https://en.wikipedia.org/wiki/Context_switch

So context switch are expensive and we should avoid them as much as possible if we are care if performance but the time never stop advancing so we can’t just cache the first result.

Handling the cost in Linux using. the Vsyscall and vDSO 

Vsyscall and vDSO segments are two ways to accelerate certain system calls in Linux. In our case, gettimeofday is accelerated using these mechanisms. vysscall was the first once to address the plenty hit so the kernel maps into the user space a page containing the current time (read-only) saving us the pressures context switch between userspace and kernel space – aka its name stands for virtual system call since the system call doesn’t actually happen. This vyscall comes with a security bridge allowing an attacker to gain control of a system call from the vyscall page in memory. This was fixed using vDSO

The vDSO (Virtual Dynamically linked Shared Objects) is a memory area allocated in userspace that exposes some kernel functionalities at user space in a safe manner. if your kernel does not have vDSO support, a traditional syscall will be made. So basically we have it covered by using these segments we are able to save the context switch and not gain an additional performance hit. For a more in depth read check this out.

This it ,basically by asking a simple question such as what is the time. we were able to learn of hardware crystal quarts context switches and Vsyscall and vDSO segments – what a trip!

Hope this post has clear some things out!

Does get the current time really affects our application performance?

Also published on Medium.

Yoni Amishav


Tech lead, blogger, node js Angular and more ...


Post navigation


Leave a Reply

Free Email Updates
Get the latest content first.
We respect your privacy.
%d