Log in

No account? Create an account

Go vs Swift vs C++ microbenchmark

Looking at the Swift vs Go vs Python battle, couldn't help but notice its old age. It was written almost 12 months ago and the weight of time clearly shows. In a fast paced race towards ecosystem simplicity that we observe nowadays, a year is a lot.

So on my Macbook Air (1.7 GHz Intel Core i5) I decided to repeat the test, and add C++ to the mix. It is too easy to test against python (which is about 10x slower than the "compiled" languages), so C++ should be a fair competition. Go 1.5.3, Swift 2.1.1, C++ clang-700.1.81.

I don't propose taking my test seriously. The micro-benchmarking doesn't tell us much about about the language ecosystem, tooling, maintainability, surface area of a language, etc, etc. It even doesn't tell us too much about performance. But you know the drill. If you see a micro-benchmark, puke and close the window. Don't read any further.

Nevertheless! There's some source.

package main
import "fmt"

func main() {
    var sum int64 = 0

    for e := 0; e < 200; e++ {
        sum = 0

        var x[]int64
        for i := 0 ; i < 1000000; i++ {
            x = append(x, int64(i));

        var y[]int64
        for i := 0 ; i < 1000000-1; i++ {
            y = append(y, x[i]+x[i+1]);

        for i := 0 ; i < 1000000; i += 100 {
            sum += y[i];
var sum : Int64 = 0

for e in 0..<200 {
    sum = 0 
    var x : [Int64] = []
    for (var i = 0; i < 1000000; i++) {
    var y: [Int64] = []
    for (var i = 0; i < 1000000-1; i++) {
        y.append(x[i] + x[i+1]);
    for (var i = 0; i < 1000000; i+=100) {
        sum += y[i]
#include <vector>
#include <iostream>

int main() {
    int64_t sum = 0;

    for(int e = 0; e < 200; e++) {
        sum = 0;

        std::vector<int64_t> x;
        for(int i = 0; i < 1000000; i++) {

        std::vector<int64_t> y;
        for(int i = 0; i < 1000000-1; i++) {
            y.push_back(x[i] + x[i+1]);

        for (int i = 0; i < 1000000; i += 100) {
            sum += y[i];

    std::cout << sum << std::endl;

Why I chose int64 instead of int? On my 64-bit platform the C++'s int is 32 bit, whereas Go's and Swift's default ints are 64-bit. I wanted to level the playing field a little.

Anyway. Let's the battle begin:

go build -o test-go go/test.go
swiftc -O -o test-swift swift/test.swift
c++ -O3 -o test-c cplusplus/test.cc
GOMAXPROCS=2 time ./test-go
        4.32 real         5.99 user         0.38 sys
GOMAXPROCS=1 time ./test-go
        3.93 real         3.89 user         0.05 sys
time ./test-swift
        3.96 real         2.82 user         1.12 sys
time ./test-c
        2.37 real         1.74 user         0.62 sys

What we see here? With Go, GOMAXPROCS adds measurable overhead. As expected. But not that huge. C++ is predictably faster. No surprise here. In fact, this appears to be mostly a competition of memory allocators and GCs (where applicable), and Swift and Go are rather on par with each other.

But let's try a smaller array so memory allocation becomes a bit less of an issue. The following test was made with e<=2000 (instead of 200) and loop iterations to 100k instead of 1m:

go build -o test-go go/test.go
swiftc -O -o test-swift swift/test.swift
c++ -O3 -o test-c cplusplus/test.cc
GOMAXPROCS=2 time ./test-go
        4.40 real         5.65 user         1.10 sys
GOMAXPROCS=1 time ./test-go
        5.06 real         5.07 user         0.83 sys
time ./test-swift
        2.32 real         2.29 user         0.01 sys
time ./test-c
        1.39 real         1.37 user         0.01 sys

Now, we're talking. Go is lagging behind, perhaps because of its reliance on its own code generator. This gets us into "3x slower than C" domain. Swift is using LLVM, the same code generator my C++'s compiler uses under the hood. But it adds some checks and GC, so Swift also exhibits a serious slowdown, though well within 2x of C++.

What we can take from it?

I suspect that if Swift had first class concurrency support while managing to retain its speed, many people would consider it instead of Go. But we can't have both. Either we have a speedy and high maintenance language, or concurrent but a bit slow language, and then Swift.

...and we also have Erlang, but its benchmark didn't fit on my charts :)

Swift, Apple Watch, and Dynamic Graphs

To Hacker News fellas: please recognize the phrase about a week worth of battery is just a joke. Today I learned that even HN trolls don't understand a concept of trolling. Read into the technical side of this writeup, ignore opinions.

I tried to write something for Apple Watch as a weekend project to polish my rough Swift skills. Swift got me rather excited. It takes some things from OCaml and FP, having a strong nod to immutability concerns. Constants are defined via let, and variable are allowed to vary through a var. Though constants are lame, as only the binding itself is constant and you can change everything inside them as usual.

Nevertheless, Swift is a step in right direction. I enjoyed programming for the most part. However, XCode was traditionally nauseous with its hiccups and interventions into my editing process.

I made an app which shows a dynamic 30fps graph inside the Watch Emulator. Incidentally, had to figure out how to made the animated gifs use solid colors, rather than being hellishly dithered. There's a two step process. First, you have to generate a single palette out of all frames. Then you apply that same palette in the second conversion. The overall workflow would look like this: use a standard QuickTime player to record a screencast, then filter that .MOV through this script to get a .GIF.

The Watch App sources are here: https://github.com/vlm/ExampleWatchGraph (look for WatchKit Extension — that's the very part that runs on a Watch).

The Watch SDK has a strong Apple-style feel, if you get my french. For example, in order to draw something dynamic on a screen, you have to do the following 30 times a second:
  1. Create a graphics context using a size known in advance. You can't just get the WKInterfaceImage dimensions, that'd be too easy. You can only set the user interface element size, not get it.
  2. Draw what's needed through a CoreGraphics (Quartz 2D, runs on a CPU) — that seems to be the easy part.
  3. Convert the context into a .PNG and assign that .PNG to the WKInterfaceImage. Check this out: https://github.com/vlm/ExampleWatchGraph/blob/master/ExampleWatchGraph%20WatchKit%20Extension/GraphPainter.swift#L117

In the end of the day, the watch battery is there just to shuffle these .PNGs around. When Apple realizes how to avoid that, the watch will last for a week instead of hours.

Here's my profiling session showing this .PNG madness:

Swift, Apple Watch, and dynamic Graphs

Поробовал я попрограммировать под Apple Watch на досуге. На Swift'е. Свифт очень даже ничё так. Похож на OCaml чем-то. Например, константы определяются через let, переменные через var. Но константы дутые: внутри них можно менять всё, что там меняется.

Swift, определённо, шаг в правильную сторону. Программировать было, в основном, приятно. Впрочем, XCode традиционно раздражал своими тормозами и подсказками.

Сделал приложение, которое показывает динамический график, движущийся со плавностью в 30fps в эмуляторе. Заодно разобрался, как сделать так, чтобы анимированные гифки были с нормальными цветами, а не все в дизере. Для этого надо сначала со всех кадров собрать палитру, затем её в дальнейшем и использовать. В итоге workflow выглядит так: обычным QuickTime'ом делается скринкаст, затем обрабатывается скриптом, делающим из .MOV → .GIF.

Исходники приложения здесь: https://github.com/vlm/ExampleWatchGraph (см. в сторону WatchKit Extension — это именно то, то выполняется на часах).

Проблема с часовым API заключается в том, что там всё через ж всё в Apple-стиле. Например, чтобы нарисовать что-то динамическое на экране, надо 30 раз в секунду:
  1. Создать графический контекст заданного заранее размера. Потому что вычислить размер WKInterfaceImage, в который вставлять будешь получившийся битмап, нельзя. Размер интерфейсного элемента можно задать (set), но не опросить (get).
  2. Нарисовать, что нужно, через CoreGraphics (Quartz 2D) — это лёгкая часть.
  3. Превратить контекст в .PNG, и уже этот .PNG разместить на WKInterfaceImage. См. здесь: https://github.com/vlm/ExampleWatchGraph/blob/master/ExampleWatchGraph%20WatchKit%20Extension/GraphPainter.swift#L117

В итоге вся батарейка на часах тратится на то, чтобы эти .PNG запаковывать и распаковывать. Как только Apple сообразит, как этого избежать, часы начнут работать неделю от аккумулятора.

Ну или я что-то не понял.

Pandoc and Manual Pages

Итак, надоело мне рисовать мануальные страницы через nroff. Как в asn1c, например:

Проблемы с подготовкой документации в nroff такие:
Проблемы с nroffCollapse )

Про Крым и медиков


Если так-то, у меня родственники в Крыму, в Алуште. Ну, то есть, можно позвонить и провентилировать, если СМИ не доверяешь. Они были рады выйти из Украины, населению же заранее рассказали, чего надо хотеть и как надо думать. Воодушевление какое-то было, как рассказывали.

Час в день дают электричество. В магазинах всё попортилось, холодильников-то нет. Супермаркеты закрылись из-за этого. Туристический сезон свернули, естественно. Хотя какой особый сезон в ноябре. Но, тем не менее.

Кстати о погоде. В Ульяновской области уже несколько учебных заведений начали готовить медработников — медсестёр, медицинских биологов, etc. Есть проблемы с тем, что эти заведения раньше кадрами для федерального НИИ атомных реакторов занимались, ещё какой-то местной спецификой. Учителей готовили, например. Теперь будут медсестёр готовить.

Медсестёр, товарищ. А если это не только в Ульяновской области? Если по всей стране медсестёр начали готовить?

Зачем стране столько медсёстр? Когда и кому они пригодятся, медсёстры эти?

Где найти столько больных? Риторический вопрос, наверное. Потому что в моём твиттере на это не ведутся. Может, потому что знают чего-то. А может, потому что наоборот.

Криптография для детей

Продолжая традицию Якова Перельмана и других русскоязычных популяризаторов науки для детей, Роман Душкин _darkus_ выпускает серию книг по областям математики и естественнонаучному мировоззрению.

Последний проект — попытка использования крауд-сорсинга на подготовку и печать этой серии приличным тиражом.


Вне зависимости от того, есть ли у вас дети и смогут ли пригодиться вашим детям подобные книги, начинание благое, а посему всячески должно быть поддержано.


Using Python to Code by Voice

У Тэвиса, у которого начался туннельный синдром, всё-таки получилось использовать dictation для программирования. Причём, он до сих пор использует голосовой ввод, даже когда его руки починились. Периодически это случается, люди находят голосовой ввод для программирования полезным.

Но я пробовал, и у меня после экспериментов с этим на два дня сел голос :( Оказывается, есть некоторые предрасположенности к RSI, которые вызывают проблемы не только со связками кистей рук, но и с голосовыми складками, когда их начинаешь использовать в большей степени, чем обычно. Но даже у Тэвиса это проблема (на 22:37). А так как обычно я молчу, любое нетривиальное использование голосовых связок вызывает RSI голосовых связок.


ULA, которая оснащала российскими двигателями свои ракеты, вышла из космической гонки. Пока временно. Но участвовать в тендерах прекратила.

«Bruno said that he remains hopeful that Congress will loosen restrictions on the RD-180 engine and change the requirements so that ULA would be able to compete for future contracts.»


Остался один SpaceX, у которого двигатели свои.

Это я не к тому, что радоваться надо. Хорошего для российского космоса тут маловато. Но на что у меня точно аллергия — это на русское шапкозакидательство, мол, космос наш, даже американцы на наших двигателях летают.

Надолго ли.


Алиска пятый день в школе («K», нулевой класс).

— Алиса, как дела у маленьких девочек?
— Хорошо!
— Что в школе изучали сегодня?
— Миссис Луша (Lucia) говорила, что у неё три куры!
— Курочки?
— Три курочки! И пришёл raccoon!
— И он курочку съел?
— Нет! Курочки с ним повоевали-повоевали, и ракун только ножку съел.
— О хосподи...
— Да, ножку у курочки съел. Она прыгает теперь на одной ножке.

— Ты вздыхаешь, а нам теперь этой курочке курятник строить... уже собрали шестьсот баксов.
— За что?
— На курятник. Чтобы деткам показывать, откуда пища берётся.
— О хосподи.

Так и живём.
Недавно деклассифицированные документы по истории развития спутниковой разведки в штатах.


Decisions during this time were made against the backdrop of this stupendous Russian space achievement. The impact on world opinion, U.S. pUblic opinion, and congressional concern was almost immediate. The shock that a backward Eurasian power could leapfrog the once mightest technological nation to achieve a first in space was the general perception. Of more specific I concern was that the Soviets had a space booster which demonstrated not only the abUlty to place objects in space, but also the capability to carry warheads to intercontinental distance. Any attempts to belittle or minimize the significance of the 184-pound SPUTNIK I satellite were dismissed wben on the third of November a second satellite, SPUTNIK II, was launched by Russia.
This satellite,weighing 1,120 pounds,placed an animal into orbit for the first time, the dog named Laika. The location of ICBM sites in Russia would now become a highest priority task for the intelligence community.


Там всё: про беспилотники в начале двадцатых, про первый радиоуправляемый дрон в 1935 году, etc. И самое главное — не прекращающий впечатлять меня вопрос про воспроизводимость и continuity проектов во времени.

During the course of the program, there was a considerable turnover of director and management personnel in the government and contractor organizations. In spite of this, the highest level of dedlcation and team spirit was maintained throughout as a continuous thread; this without doubt contributing significantly to program success. (Шрифт мой — lionet)

P.S. Помню статью про то, как на американских авианосцах устроена continuity, при том что кадровый состав полностью меняется менее чем за два года: The Self-Designing High-Reliability Organization: Aircraft Carrier Flight Operations at Sea.