I decided to continue the cycle of articles about the Aurora OS (until recently called Sailfish). During the time that I work with this OS, I have accumulated various observations related to the performance of applications on Qt and the system as a whole, because various devices are hung, like a Christmas tree, I notice all the little things at startup. I think that this can be interesting and useful to colleagues who also work with Qt (or will work soon). Suggest that you can test more.
I program in Qt and often discuss with colleagues, iOS developers, the similarities, differences, and benefits of approaches. At some point we decided to move from words to deeds and take measurements. We could not find an Android programmer who is ready to participate in our entertainment, so a comparison involving figures and tables will be only for Swift and C ++.
I want to remind you that Qt / C ++ does not impose its own memory management mechanism, and the user solves this issue within the capabilities available in C ++, while Swift uses reference counting, and in Java, the garbage collector. Thus, the programmer has the opportunity to interact with memory more efficiently. In order to send an http request or read data from a database, Qt relies on its own strength, rather than using the ready-made frameworks provided by the OS. Exceptions are interaction with the keyboard, drawing the application's start window, displaying notifications and other things. ')
Test 1.
First of all, we decided to write a simple algorithm (the sieve of Eratosthenes), run it on large numbers and compare the computation time. Launched on iPhone 7.
Swift program:
swift // // ViewController.swift // Eratosthenes // // Created by Dmitry Shadrin on 22/11/2018. // Copyright 2018 Digital Design. All rights reserved. // import UIKit class ViewController: UIViewController { @IBOutlet weak var digitTextField: UITextField! @IBOutlet weak var timeLabel: UILabel! @IBAction func startAction(_ sender: UIButton) { guard let text = digitTextField.text, let number = Int(text) else { return } prime(n: number) } func prime(n: Int) { let startTime = DispatchTime.now() let _ = PrimeSequence(upTo: n) .reduce(into: [], { $0.append($1) }) // let endTime = DispatchTime.now() let time = (endTime.uptimeNanoseconds - startTime.uptimeNanoseconds) timeLabel.text = "\(time)" } } public struct PrimeSequence: Sequence { private let iterator: AnyIterator<Int> public init(upTo limit: Int) { self.iterator = AnyIterator(EratosthenesIterator(upTo: limit)) } public func makeIterator() -> AnyIterator<Int> { return iterator } } private struct EratosthenesIterator: IteratorProtocol { let n: Int var composite: [Bool] var current = 2 init(upTo n: Int) { self.n = n self.composite = [Bool](repeating: false, count: n + 1) } mutating func next() -> Int? { while current <= self.n { if !composite[current] { let prime = current for multiple in stride(from: current * current, through: self.n, by: current) { composite[multiple] = true } current += 1 return prime } current += 1 } return nil } }
I will not dwell on the code in detail; linear Eratosthenes are not obvious for understanding, especially if one of the languages ​​is not familiar to you. Here is a link with the description: https://e-maxx.ru/algo/prime_sieve_linear , who is interested, can check for honesty. By the way, the swift version turned out to be slightly more optimized in the details (you can search for them), which didn’t stop the plus version from winning in performance.
Run the program. Applications have a field for entering the number n, a start button and a field with the total time:
Swift - on the left, Qt - on the right.
Result. I will give a table of measurements for different n and at different points in time: As you can see, an application in C ++ is ~ 1.5 times faster than native with identical algorithms.
Test 2.
Naturally, computing in the context of mobile applications is an important thing, but far from the only one. Therefore, we drew a ListView consisting of 1000 elements, each of which contains text and a picture, in order to see more about the drawing speed of graphic elements. Below, in the videos, you can see the result:
Qt:
Swift:
Visually, the difference is not noticeable.
Test 3.
In the Sailfish OS, we have the Linux kernel and the graphical native shell on Qt, and this in itself gives rise to thoughts about the good performance of this OS. I often notice that the Inoi R7 wins in terms of the speed of execution of some tasks, although the Samsung Galaxy S8 is also close by. For example, Samsung Galaxy S8 sends, accepts, processes, packs into a database, etc. 10K http requests in about 3-4 minutes, and Inoi R7 does the same for about 5-6 minutes. Given the difference in iron performance, the result is impressive.
For a more honest test of the OS performance, I decided to look at the speed of the response of the wheelbarrow.
Simple and straightforward. I don’t have a phone that supports Sailfish and Android for my personal use, so I had to look for the phone with my colleagues as close as possible to Inoi r7, but on Android. What suddenly turned out to be very difficult, considering that I am sitting in a mobile development office.
Sony Xperia Z5 compact: The processor - Qualcomm Snapdragon 810 MSM8994, 2000 MHz The number of processor cores - 8 Video Processor - Adreno 430 The amount of internal memory - 32 GB The amount of RAM - 2 GB
Inoi R7: Processor - Qualcomm Snapdragon 212 MSM8909AA, 1200 MHz The number of processor cores - 4 Video Processor - Adreno 304 The amount of internal memory - 16 GB The amount of RAM - 2 GB
Sony still turned out to be more powerful, but for the odds equation we turn on the power saving mode on it, it still does not lead to complete equality of power of the devices. On the video you can see that on Android the line is not as smooth as on Sailfish.
On the left - Sony, on the right - Inoi:
I do not argue, this is not a very serious indicator, you need to compare not only the capabilities of a pure language, but also different libraries, native and cross-platform, compare their performance and usability, because there are very few applications that use only ListView and Eratosthenes sieve. Although all these little things together look very convincing to me.
Minuses
Of course, everything is not so rosy with Qt, as I try to paint here, there are downsides. For example, by working with TextInput on Android, you can torture perfectionists who are particularly sensitive to crutches, because on each Qt device it manages to put absolutely unique poles into the wheels when interacting with the keyboard. On one phone, the picture goes up, on the other - it stands still, but EnterKey does not work, on the third one only capital letters are entered, and not to be persuaded to switch to lower case. You can continue indefinitely. And all this also slows down! (Grunts are relevant only for Android, such problems do not arise on Sailfish, everything works fine). In addition, Qt is difficult to achieve native appearance of the application.
Conclusion
The main conclusion that can be made: Qt, being a cross-platform tool, is not inferior in performance to native development tools. It is perfect for programs in which, in addition to the GUI, there is still a lot of mathematics, and especially for corporate applications, where there are many nuances and few employees, so that for each OS not to create a standalone version. Corporate users are more important features than native UI. For Aurora, Qt is a native tool for developing applications, which probably gives some performance boost.
It would be interesting to test the Aurora on a powerful hardware, like my Galaxy S8.