Kotlin/Native vs. C++ vs. Freepascal vs. Python: Measuring FPS, RAM and CPU Usage, Size of the Compiled Executable File Across Codebases | by Alex Maryin | May, 2022

A comparability

Starfield animation of Python app

Howdy, everybody! As I promised within the first a part of this blog-post sequence, I pleasure to welcome you into the second a part of our journey the place I’m looking for the reality evaluating Kotlin/Native with C++, Freepascal, and Python by means of its efficiency with openGL graphics and coding pleasure.

Contents

  1. Simple math with native apps, or who’s so clever tonight?
  2. Graphic take a look at with SDL2, or Throughout the Universe with Norton Commander. — you might be right here —

Motivation

This post by Vyacheslav Arkhipov impressed me to begin the analysis. In case you are oldy geek it’s best to do not forget that previous CRT-displays for PC had a burn-in impact.

Wiki: Burn-in is when photos are bodily “burned” into the display of the CRT; this happens resulting from degradation of the phosphors resulting from extended electron bombardment of the phosphors, and occurs when a hard and fast picture or emblem is left for too lengthy on the display, inflicting it to seem as a “ghost” picture or, in extreme instances, additionally when the CRT is off. To counter this, screensavers had been utilized in computer systems to attenuate burn-in. Burn-in just isn’t unique to CRTs, because it additionally occurs to plasma shows and OLED shows.

And the one of many well-known screensavers for PC was Starfield which it’s best to see beneath the title of this put up. Think about you might be commander Jameson inside of the Cobra MK3 and you might be enrouting throughout the Universe looking for Targoids craft. Stars are dashing round and you quicker than lightning in 100 instances…

Ranging from Python

I’ve up to date a bit the code from authentic supply to print FPS within the window’s title, to make use of different drawing capabilities for getting anti-aliasing impact and so as to add variable radius property for star, thus stars acquired a easy rising impact:

It’s full code in Python, however don’t overlook to put in Pygame library if you wish to reproduce this one in your machine.

The toughest half is to show it into different languages. Pygame library itself makes use of SDL graphic library to encapsulate low-level interfaces with openGL (or DirectX on Home windows). All we want is to write down our personal xxGame engine for every language… Uuh. Let’s go.

C++ pole-position

I feel, the easy option to start is to implement the Starfield is on the native platform for SDL, i.e. C++ language, after which flip it into Kotlin or Freepascal variants.

Disclaimer: As a result of I’m not acquainted so much with direct SDL programming on C++ I’ve studied its fundamentals from video sequence by Carl Birch on YouTube here and I like to recommend them as an ideal begin.

Let’s get away from Python code above and use ++ advantages of the language. C++ has two sorts of lessons which we are able to use: class itself and struct. The distinction between them is how class members are declared by default, as personal or as public members. In any other case each class and struct are comparable.

I declare the struct Star and encapsulate its habits for creating, updating and revival:

It has a default constructor which invokes the newStar perform and comparable additionally occurs when this star is moved off the display. We are going to use an array (vector within the phrases of C++ STL) of Star objects as an alternative of world checklist with unnamed parameters as introduced in Python.

After all, we may use a static array in plain C++ as an alternative of dynamic vector as a result of we already comprehend it’s measurement, however I desire to make code with some alternatives for future enhancement. For instance, we are able to dynamically enhance or lower stars quantity with vector in runtime.

Initially of our major perform in C++ program we should always put together SDL engine to drawing:

Right here two pointers can be created for the SDL window and Render context. Sure, we may create any variety of home windows and render contexts with SDL. All the following used SDL capabilities which carry out drawing ought to use render context and another capabilities want a window pointer for execution.

However there’s a little downside… SDL has no perform to attract a crammed or a defined circle from the field! Due to Github, I discovered the mandatory algorithm in a matter of seconds. That code makes use of Bresenham’s circle algorithm and is supplied us by Gumichan01 beneath the MIT license. All sensible — simply! Look, how’s easy to attract a rastered circle:

So, now we’re able to the principle code:

I’ve skipped some components of the code however you could clone the total undertaking from my repository.

So, as you’ll be able to see I wrote a quite simple code in C++ and it’s virtually much like Python code with the one distinction being the use struct and encapsulating some behaviour. This code needs to be a begin level for the following one, in Kotlin. Let’s have a look at, how we may improve this code with out efficiency breaks.

Programming on plain openGL and SDL is a stable structural sequence of capabilities with none logical blocks or practical scopes inside. The next pseudo-code is exhibiting actually what I imply:

init all;
clear display; // suppose, 1st body
draw level;
swap buffers;
clear display; // 2nd body
draw strains;
draw triangles;
draw the rest;
swap buffers;
clear display; // third body, and so forth.

This can be a normal move that could possibly be run in any C/C++ program. After all, you possibly can use logical blocks and arrange drawing frames your self, however the framework doesn’t drive you to it.

Kotlin brings alternatives to construct your code in declarative fashion utilizing DSL. With DSL you’ll be able to wrap one logical block into one other and specify restrictions for its scope or sequence of invocation of blocks with clear and concise syntax. In case you are already accustomed to Ktor or one other Kotlin framework constructed with DSL fashion, you perceive me. By the best way, 2D sport engine LibGDX well-known in JVM world has Kotlin enhancements known as LibKTX which makes doable to make use of DSL fashion and develop video games quicker with clear, auto-explaining code.

I used to be learning the best way to use this framework on the sequence of video by Quillraven ‘LibGDX Kotlin tutorial’ till I constructed my first easy multi-platform sport Deter revolution. And now Quillraven is constructing his personal light-weight ECS (entity component system) engine known as Fleks on the highest of LibGDX utilizing Kotlin DSL.

However, no phrases! Let code to point out what I imply:

SDL Engine 
init Engine()
init Atmosphere()
add Occasion Listener
for stop occasion -> cease engine and shut app

begin Infinite Loop
on Every Body
draw magic
present FPS


That’s how I think about the principle code of Kotlin variant of Starfield! It’s possible you’ll be amazed that DSL permits to show that pseudo-code in Kotlin actually one-to-one:

It’s lovely, isn’t it? This can be a complete major perform. SDLEngine is a perform with the receiver of an Engine class. Within lambda (which is a final parameter of perform), the occasion of this class is out there as this variable, and you may exclude it in codeword this if it isn’t interfering with another upward scope receiver.

I moved engine initialization parameters into SDLEngine perform — width and top of the window. addEventListener is a perform contained in the engine scope that will be invoked on every occasion from the engine.

startInfiniteLoop can also be perform contained in the engine scope which turns graphic renderer on. In my easy engine this perform can be operating till the window be closed. onEachFrame is the perform with receiver of SDL Renderer pointer which wants for any SDL drawing perform. I declared renderer as a personal member of the Engine class and also you gained’t get it exterior of onEachFrame perform, so you’ll be able to’t draw something exterior body.

For my part, that declarative fashion permits you to keep away from errors and brings extra readability and ease. However for the primary…

Find out how to embody SDL lib in Kotlin/Native

This was actually difficult a part of my discovery, however my current physique of data permits you to go this fashion quicker. At first, it’s best to set up SDL2 it into your machine. I used Ubuntu and all what I would like is sudo apt set up libsdl2-dev. Installation is more different for other platforms.

Then it’s best to research rigorously backward and forwards subsequent tutorials and articles from official Kotlin docs:

  1. Get started with Kotlin/Native in IntelliJ IDEA. This tutorial introduces fundamentals of native utility constructing in Kotlin utilizing IDEA.
  2. Interoperability with C. That is crucial half! It describes the best way to embody third events dynamic libraries into your undertaking. There are lots of particular issues with every library regarding solely it. And don’t skip the a part of Bindings! It’s very essential in case you plan to make use of C++ sorts like pointers, enums, lessons/structs and callbacks.
  3. Mapping primitive data types from C. As I didn’t nonetheless say that it’s an important half too?

So, having regard to that tutorials, I created the following directories contained in the undertaking: undertaking/src/nativeInterop/citerop and put a file sdl2.def into it. The file incorporates this:

package deal = platform.SDL2
headers = SDL2/SDL.h
compilerOpts = -I/usr/embody -I/usr/embody/x86_64-linux-gnu -I/usr/embody/SDL2 -D_POSIX_SOURCE
compilerOpts.linux = -D_REENTRANT
linkerOpts = -L/usr/lib/x86_64-linux-gnu/ -L/usr/lib64 -lSDL2

Then, I edited construct.gradle.kts undertaking file including to kotlin/nativeTarget extension the next:

compilations.getByName("major") 
cinterops
val sdl2 by creating

After that (and naturally Gradle sync) I discovered a brand new job known as cinteropSdl2Native within the Gradle duties device window. It’s essential to run this job earlier than you attempt to use any of the headers from *.def recordsdata.

It’s not a end! In any case of that, it’s time to rebuild the undertaking. And now we are able to import new package deal platform.SDL2 (title is outlined in .def file).

So, now we are able to flip DSL to SDL! That’s a reasonably anagram. Here’s a full code of file with my SDL engine:

It’s doing something the identical as his C++ brother however encapsulating it away from consumer [of SDL]. Star class I outlined is a plain class, not an information class, as a result of it permits to keep away from pointless generated code which useful for information lessons after they compares with one another. This isn’t wanted for my program.

The repository with remainder of code you could discover here on my Github.

Freepascal SDL utilization

Freepascal includes SDL headers from the box since model 2.2.2. However we want SDL2 headers. The location https://www.freepascal-meets-sdl.net/ may help us. Additionally, it’s a excellent place to begin learning SDL2 in Pascal if you’re new to it.

Obtain Pascal headers for SDL2 from this Github repo and place it into preferable listing (I all the time set default listing which Lazarus created in /residence/consumer/.lazarus).

Then please rigorously learn tutorials from the talked about website and browse.me from the repository, as a result of Pascal interop modules produce other kind names not comparable for C++ sorts. In addition to Kotlin c-interop preparations, doesn’t it?

Under is the perform transformed from C++ for circle drawing in Freepascal:

And it is a full code for Freepascal much like the C++ variant:

Contest and outcomes

Lastly, we are able to begin with our starting thought. Let’s construct a launch for every language (I do know, I do know, Python, you’ll be able to’t) and see how briskly is it and the way small is it.

This can be a specification of my laptop computer which I’ve used for coding and testing: Acer Aspire 3, 8 Gb RAM, CPU Intel Core i3–1005G1, 240 Gb NVME m.2 disk, Ubuntu 22.04 x64, OpenGL 4.6, SDL2, and final variations of Intellij IDEA, VS Code, Lazarus and PyCharm, OBS for display capturing.

I’ve measured the dimensions of the executable file, FPS with 200 stars, and used reminiscence and CPU loading. I’ve captured with OBS how the entire packages ran however OBS has eaten virtually a half of all sources, that’s why FPS on the video was smaller than in pure checks:

I acquired the next pure outcomes with 200 stars of Starfield:

FPS with 200 stars

The result’s the proof of all proofs. However suppose, I gained’t go to date if I say that a bit distinction between C++, Freepascal, and Kotlin is just statistical.

Speaking Python, I feel, PyGame has its personal optimization technique and FPS smaller than 500 just isn’t a floor for tragedy. Additionally, I don’t know what circle algorithm PyGame makes use of precisely, nevertheless it appears a bit completely different than our customized one for others.

However let’s shake the machine and get away from infantile issues. Who’s want 200 stars? Let it draw 5000!

Throughout the display capturing when OBS was consuming a half of sources once more (and my knees had been burning by laptop computer’s warmth) the FPS was virtually the identical for all of our contestants! And it was superb for me. However the outcomes of pure take a look at shocked me much more:

FPS with 5000 stars

Are you see this? Pure C++ program, pure Freepascal program, and pure Kotlin/Native program take actually the identical sources and provides actually the identical FPS. However in case you scroll up it will likely be clear, that the code of the Kotlin program is extra difficult than the code of C++ and Freepascal one. We wrote a fancy DSL logic for our consolation later, nevertheless it doesn’t have an effect on runtime efficiency — it wants the identical RAM, the identical CPU load because the smaller low-level code. Even the dimensions of the exe file is smaller by 3 instances than Freepascal file (with out debug data).

After all, Kotlin as a younger language doesn’t have a giant, commerce graphic engine like Unity3D for C# or UnrealEngine for C++, nevertheless it has an ideal alternative to get its personal place on this world. I consider it’s solely starting of nice and lengthy story!

As for me, I’ve acquired all proof that selecting Kotlin was the precise determination of my current years: Android cellular, back-end, desktop purposes, 2D and 3D video games — all of those roads are opened for Kotlin.

Thanks for fully studying to this end line!

More Posts