C vs php vs hhvm vs go simple benchmark

Last time i do many thing starting from small utilities and up to big projects in golang. And many friends ask me why… first time i just said that golang is simple and cool :) But now i decided to do simple benchmark to show why…
So, used interpreters/compilers:
PHP:

$ php --version
PHP 5.6.4-4ubuntu6 (cli) (built: Apr 17 2015 15:47:51) 
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2014 Zend Technologies
    with Zend OPcache v7.0.4-dev, Copyright (c) 1999-2014, by Zend Technologies

HHVM:

$ hhvm --version
HipHop VM 3.7.2 (rel)
Compiler: tags/HHVM-3.7.2-0-gfc9f29b2799933d8215faaadfa83de722df64e26
Repo schema: 34f16546e395aed44ad434467b6f96c89b0d8a8b

C:

$ gcc --version
gcc (Ubuntu 4.9.2-10ubuntu13) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Go:

$ go version
go version go1.4.2 linux/amd64

And all of this on laptop with i3-4030U CPU @ 1.90GHz and 16GB RAM

PHP (& HHVM) code:

<?php
  $a = 0;
  for ($i = 0; $i < 1000000000; $i++)
    $a += $i;
  print "$a\n";

C code:

int main()
{
  long a = 0;
  for (int i = 0; i < 1000000000; i++)
    a += i;
  printf("%ld\n", a);
  return 0;
}

Go code:

package main

import (
    "fmt"
)

func main() {
  a := 0
  for i := 0; i < 1000000000; i++ {
    a += i;
  }
  fmt.Println(a)
}

And… results:

PHP:
User time (seconds): 68.01
System time (seconds): 0.09
Maximum resident set size (kbytes): 14628

HHVM:
User time (seconds): 37.40
System time (seconds): 0.08
Maximum resident set size (kbytes): 110144

GCC -O0:
User time (seconds): 4.06
System time (seconds): 0.03
Maximum resident set size (kbytes): 1372

GCC -O3:
User time (seconds): 0.48
System time (seconds): 0.00
Maximum resident set size (kbytes): 1404

GO:
User time (seconds): 0.52
System time (seconds): 0.00
Maximum resident set size (kbytes): 1632

And this is an answer why do i use go almost for anything :) Development is as simple as in PHP or Python, but resulting binary only a bit slower than plain C.
So as for me “application speed”/”development speed” is awesome for most cases.

P.S.: no Java, Scala, Python and other languages in benchmark only due to i don’t use them as often as C/C++/PHP/Go

Unity-style window activation in KDE

I have used unity in Ubuntu for a long time and i’m very used to use Win+[number] key combination to switch to windows. For example i have Win+1 to switch to terminal emulator.
Some months ago I have tried new KDE5 and it was awesome. But I found no way to activate (or launch if not started) application on shortcut :-( Only lunch a new one every time, but it’s not what i want.
After 2 minutes of googling I found wmctrl utility (exist in universe repository) and 2 more minutes for scripting give me something like this:

#!/bin/bash

app=$1

if [ `wmctrl -l -p | grep \`pgrep $app\` | wc -l` != 0 ]
then
  wmctrl -i -a `wmctrl -l -p | grep \`pgrep $app\` | awk '{ print $1; }'`
else
  $app &
fi

Using pgrep is needed because of konsole sets windows title to current path or host and wmctrl can’t find it by title.

After setting up shortcut in ‘system-settings’ to my favorites like konsole, qtcreator i’m really happy now šŸ˜€

QHash and QMap in threaded application

As you know QMap/QHash are little bit faster than std::map and std::unordered_map … but why? I have no ideas about this before I have used them in high-load muti-thread application. I send data in QHash via queued signal/slot between threads. Anything looks fine, but 1-2 times per day application gets segfault. It was very strange because it crashed after different count iterations but it was millions iterations. GDB shows something like this:

#0  0x00007f8421029107 in __GI_raise (sig=sig@entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1  0x00007f842102a4e8 in __GI_abort () at abort.c:89
#2  0x00007f8421067044 in __libc_message (do_abort=do_abort@entry=1, 
    fmt=fmt@entry=0x7f8421159c40 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:175
#3  0x00007f842106c81e in malloc_printerr (action=1, str=0x7f8421159d90 "double free or corruption (out)", ptr=<optimized out>)
    at malloc.c:4996
#4  0x00007f842106d526 in _int_free (av=<optimized out>, p=<optimized out>, have_lock=0) at malloc.c:3840
#5  0x00007f8421ede054 in QHashData::free_helper (this=0x7f8418003a80, 
    node_delete=0x40b324 <QHash<unsigned long, logdata>::deleteNode2(QHashData::Node*)>) at tools/qhash.cpp:496
#6  0x000000000040b364 in QHash<unsigned long, logdata>::freeData (this=0x7f84180bb5e0, x=0x7f8418003a80)
    at /usr/include/x86_64-linux-gnu/qt5/QtCore/qhash.h:600
#7  0x000000000040f208 in QHash<unsigned long, logdata>::~QHash (this=0x7f84180bb5e0, __in_chrg=<optimized out>)
    at /usr/include/x86_64-linux-gnu/qt5/QtCore/qhash.h:310

after some days of hard debug, Qt source code reading and liters of green tea i have found that different instances of QHash (and also QMap) may share some data structures. And they may reuse and/or free some internal data structures in different instance of QHash (or QMap). This works perfect in single thread application or if you don’t transfer data between threads but may crash you application in other case.
And there is simple solution issuing a little bit slowdown of inserting/deleting elements in QHash/QMap:

  QHash<QString,int> *sharedHash = new QHash<QString,int>;
  sharedHash->setSharable(false);

And anything goes OK. Or you can use std::unordered_map or std::map :)

QtCreator 3.3 and Ubuntu (Unity) 14.10 global menu

To compile global menu plugin (as show in previous post) we need also one-line code modification due to using Qt 5.4 in QtCreator:

--- appmenuplatformmenubar.cpp.orig     2014-12-12 14:02:46.059940656 +0100
+++ appmenuplatformmenubar.cpp  2014-12-12 14:02:55.943940215 +0100
@@ -301,7 +301,7 @@
 
 
 KdeAppMenuPlatformTheme::KdeAppMenuPlatformTheme(const QString &kdeHome, int kdeVersion)
-    : QKdeTheme(kdeHome, kdeVersion)
+    : QKdeTheme(QStringList(kdeHome), kdeVersion)
 {
 }

Qt meta-object system

What is is and why we need it?


From the Qt documentation we know that “Qt’s meta-object system provides the signals and slots mechanism for inter-object communication, run-time type information, and the dynamic property system.” [1]. I hope everyone knows what is signal-slot in Qt and why you need Q_OBJECT macro at the beginning of each class declaration.
Meta-object is also used for object casting using qobject_cast template function. It’s much more safe then build-in C++ cast functions and often is much faster. So qobject_cast(some_object) is better than dynamic_cast(some_object). Trust me :)

Deeper look


What is more interesting is how meta-object is implemented. Q_OBJECT macro adds some private declarations to each type (Q_OBJECT adds much more, but only thouse are interesting at this moment):

const QMetaObject *metaObject() const;
void *qt_metacast(const char *className);
int qt_metacall(QMetaObject::Call call, int id, void **arguments);

QMetaObject contains many useful information about class and object such as class name, properties, methods and so on. qt_metacast function is used by qobject_cast and I can’t image situation when I need call it directly. But qt_metacall function can be used to call method, read/write/reset property and do some other magic things :) which is defined by first argument (for example use QMetaObject::InvokeMetaMethod for method call). Second argument is method (or property) index and the third one is array of arguments (the first one is return value and maximum of 9 arguments can be passed to method). You can say that we need to know list of arguments and return type to call any function. You are right and QMetaObject offers this information. For example this code lists all public slots of self:

const QMetaObject *meta = metaObject();
for (int id = 0; id < meta->methodCount(); ++id) {
  const QMetaMethod method = meta->method(id);
  if (method.methodType() == QMetaMethod::Slot && method.access() == QMetaMethod::Public)
    qDebug() << method.name();
}

Information about return type and parameters can be retrieved by returnType() and parameterNames()/parameterTypes() methods.

Why i’m talking about all this things?


Using this information we can do many interesting things like creating object instances by class name

QObject *object = static_cast<QObject *>(QMetaType::create(QMetaType::type("QButton")));

so we can, for example, specify class name of some object in config and … call methods of this object also by name

object->qt_metacall(QMetaObject::InvokeMetaMethod, object->metaObject()->indexOfProperty("hello"), 0);

Real life example


As a real life example I can show you my old library (qtfjsonrpc) where i used meta-object system to simplify writing of APIs use json-rpc.

Thank you for reading :)
Comments are welcome

Enabling global menu in Qt Creator in Unity (Ubuntu 14.04)

I have just installed Qt 5.3.1 from qt-project.org and…. Qt Creator doesn’t supports global menu in Unity :-( Goggling doesn’t helps me at all.
After a little bit tracing I see that it uses it’s own plugins directory and of course it have no libappmenu-qt5.so
So we need just few commands to fix this:

sudoĀ aptāˆ’getĀ installĀ libgtk2.0āˆ’devĀ libdbusmenuāˆ’qt5āˆ’dev
cdĀ /tmp
aptāˆ’getĀ sourceĀ appmenuāˆ’qt5
cdĀ appmenuāˆ’qt5āˆ’0.3.0+14.04.20140415/src
~/Qt/5.3/gcc_64/bin/qmakeĀ src.pro
make
testĀ āˆ’dĀ ~/Qt/Tools/QtCreator/bin/plugins/platformthemesĀ ||Ā mkdirĀ ~/Qt/Tools/QtCreator/bin/plugins/platformthemes
cpĀ libappmenuāˆ’qt5.soĀ ~/Qt/Tools/QtCreator/bin/plugins/platformthemes
chmodĀ 755Ā ~/Qt/Tools/QtCreator/bin/plugins/platformthemes

 

thats all :)
qt-creator