[PyKDE] Re: [Kde-bindings] Language Overhead: C++ vs Python

Richard Dale Richard_Dale at tipitina.demon.co.uk
Wed Apr 6 12:42:00 BST 2005


On Wednesday 06 April 2005 14:24, Phil Thompson wrote:
> I've been meaning to do this for ages - maybe it will be useful for people
> who are trying to convince management types how unproductive C++ is.
>
> Please note, although the comparison here is with Python, I'm sure that
> similar figures would be obtained for any similar language.
>
> From time to time we get commissioned to develop Python bindings for Qt
> based widget sets. These often come with examples and part of the work is
> to port those examples to Python. We then end up with C++ and Python
> implementations with the same structure, the same functionality, and
> calling the same API. Any difference in the amount of code is purely down
> to "language overhead".
>
> Below is a comparison of the numbers of lines of code for a number of such
> examples. For the C++ implementations I have excluded all .pro files and
> all qmake and moc generated files.
>
>              C++   Python   Reduction
> example_1    509     318       38%
> example_2    871     516       41%
> example_3    225     132       41%
> example_4    142      72       49%
> example_5    615     363       41%
> example_6     56      46       18%
> example_7   1445     764       47%
> example_8    536     312       42%
Probably most of the lines saved are because you don't need to duplicate 
method definitions in the .h files for languages like python or ruby. Most of 
the time one line of C++ in the .cpp file becomes one line in the .py or .rb

I think there is more a saving when you write the app in a way which you 
couldn't do in C++. A good example of that is the PyKDE uisampler app, it 
puts various names in a nested hash:

listItems = {"Dialogs":
                {"KAboutDialog": ["KAboutApplication", "KAboutContainer", 
"KImageTrackLabel",\
                                  "KAboutContainerBase", "KAboutContributor", 
"KAboutWidget"],\
                "KAboutKDE": [],\
                "KBugReport": [],\
                "KColorDialog": [],\
...

The pulls stuff out of the hash and uses 'eval' to invoke the code:

    def lvClicked (self, lvItem):
        if not lvItem:
            return

        if lvItem.text (0).latin1 () in listItems.keys ():
            return

        p = lvItem.parent ()
        if p.text (0).latin1 () in listItems.keys ():
            pfx = prefix [p.text (0).latin1 ()]
            funcCall = pfx + lvItem.text (0).latin1 () + "(self)"
        else:
            pfx = prefix [p.parent ().text (0).latin1 ()]
            funcCall = pfx + lvItem.parent ().text (0).latin1 () + "(self)"

        eval (funcCall)

I translated it into ruby easily, but you just couldn't do it in C++:

$listItems = {"Dialogs" =>
                {"KDE::AboutDialog" => ["KDE::AboutApplication", 
"KDE::AboutContainer", "KDE::ImageTrackLabel",
                                  "KDE::AboutContainerBase", 
"KDE::AboutContributor", "KDE::AboutWidget"],
                "KDE::AboutKDE" => [],
                "KDE::BugReport" => [],
                "KDE::ColorDialog" => [],
... 

    def lvClicked(lvItem)
        if lvItem.nil?
            return
	end

        if $listItems.keys().include?(lvItem.text(0))
            return
	end

        p = lvItem.parent()
        if $listItems.keys().include?(p.text(0))
            pfx = @prefix[p.text(0)]
            funcCall = pfx + lvItem.text(0).sub("KDE::","K") + "(self)"
        else
            pfx = @prefix[p.parent().text(0)]
            funcCall = pfx + lvItem.parent().text(0).sub("KDE::","K") + 
"(self)"
	end
        eval funcCall
   end

-- Richard




More information about the PyQt mailing list