Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: A little more abstraction  (Read 11257 times)

0 Members and 1 Guest are viewing this topic.

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
A little more abstraction
« on: July 09, 2010, 08:56:09 am »
Hi guys,

as I'm currently synchronizing PySFML to trunk (SFML2), I've realized that it'd be maybe a good point of time to bring in some more abstraction to PySFML.

As some of you maybe know, PySFML is directly created by using the Python C API. The advantage is no garbage and full control over the sourcecode.

However, maintaining such a library (which is getting bigger and bigger) just with the Python C API is a hard and sometimes annoying task, not speaking of the attention you have to pay, because many things can go wrong without even being recognized.

So my proposal is to bring in a higher level of abstraction for creating the binding. Personally, I've had made very good experiences with Boost.Python. Binding classes (or other types) to Python works with ease and is not as much error-prone as the direct approach (Boost.Python takes care of most of the internal stuff).

The drawback is that this throws in a dependency (Boost.Python) that's needed to build the binding library (it's *not* needed for using it). But I think it's worth it -- especially regarding to the time that can be saved by synchronizing PySFML to trunk.

So I really would love to hear your opinions about this -- won't make this step without acquiring vogue. :)

Svenstaro

  • Full Member
  • ***
  • Posts: 222
    • View Profile
A little more abstraction
« Reply #1 on: July 09, 2010, 11:55:33 pm »
I think it's a good idea. I've work with Boost.Python quite a bit and I'll call it stable and easy to work with. As for the build deps, about any Linux system will have Boost installed and any serious Windows C++ developer will also have it. I don't consider it a problem at all.

Boost is pretty much a given.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
A little more abstraction
« Reply #2 on: July 10, 2010, 03:20:10 pm »
I remember reading that PySide (the new official Python binding for Qt) had performances issues when they were using boost.python to implement the binding.

I think you can find some useful discussions, for example:
http://www.pyside.org/pyside-v0-3-benchmarks/
Laurent Gomila - SFML developer

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
A little more abstraction
« Reply #3 on: July 10, 2010, 04:09:13 pm »
Thanks for your feedback.

I'll check that article out, thanks.

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
A little more abstraction
« Reply #4 on: July 10, 2010, 04:16:38 pm »
Okay, took a short overview.

1. The performance tests can't be really compared, since it's Qt stuff.
2. Creating 10,000 objects in a row with < 2 seconds is still fast if you asked me.

My conclusion is that if the performance impact for SFML calls isn't really noticeable, something like Boost.Python is definitely the better alternative here, since it makes things so much easier and better maintainable.

When the load is *really* high, you'd outsource the time critical parts to a C(++) library -- even with the pure Python C API.

What I'll do next is a benchmark with some massive sprite and text rendering to be able to compare both versions. I hope to get valuable answers to performance and memory consumption questions here.

Thanks again for your thoughts.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
A little more abstraction
« Reply #5 on: July 10, 2010, 06:04:12 pm »
Quote
What I'll do next is a benchmark with some massive sprite and text rendering to be able to compare both versions

Yep, I think this is necessary before making your final decision.
The overhead may not be noticeable for a single function call, but when you call hundreds of SFML functions per second, things may be different :)
Laurent Gomila - SFML developer

Calmatory

  • Newbie
  • *
  • Posts: 16
    • View Profile
A little more abstraction
« Reply #6 on: July 21, 2010, 01:31:00 pm »
Have you already benchmarked anything? If so, with which results?

I'd suggest posting the source code along with the results.
The amount of effort we put into something arbitrary we do in our everyday lives is proportional to the amount we gain from it. It's fascinating how this applies to everything in our lives. Your task is to try to enjoy and make the most out of it.

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
A little more abstraction
« Reply #7 on: July 22, 2010, 01:53:12 am »
I'm making good progress with the Boost.Python approach. Currently creating a window works flawlessly, now I'm going to throw in sf::Sprite and sf::Image to finally get some benchmarking results.

By the way, my experiments are for SFML 1.6, since there's no up-to-date binding for the latest SFML 2 trunk, yet. However, when this works out, I don't think a binding for SFML 2 would be slower.

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
A little more abstraction
« Reply #8 on: July 22, 2010, 02:55:45 am »
Well, here are the first results. Boost.Python performs a lot slower than the raw approach.

The test suite just opens render window, loads an image, creates a sprite and renderes that sprite onto the render window with random positions.

Used Python version is 2.6, SFML version 1.6. The source code for both cases is identical except naming conventions.

Boost.Python
10 iterations took 0.0014 seconds.
100 iterations took 0.0013 seconds.
1000 iterations took 0.0114 seconds.
5000 iterations took 0.0588 seconds.
10000 iterations took 0.1132 seconds.
50000 iterations took 0.5619 seconds.
100000 iterations took 1.1588 seconds.

Raw Python C API
10 iterations took 0.0006 seconds.
100 iterations took 0.0010 seconds.
1000 iterations took 0.0066 seconds.
5000 iterations took 0.0337 seconds.
10000 iterations took 0.0634 seconds.
50000 iterations took 0.3118 seconds.
100000 iterations took 0.6288 seconds.

Conclusion
Nearly in all cases the raw approach performs 2 times faster than Boost. This is not acceptable in my opinion, since applications/games using (Py)SFML do need the speed.

Here's the source code which I've used for testing:
Code: [Select]
import sf
import time
import random

window = sf.RenderWindow( sf.VideoMode( 1024, 768, 32 ), "Test" )

image = sf.Image()
image.load_from_file( "foobar.png" )

sprite = sf.Sprite()
sprite.set_image( image )

window.clear( sf.Color( 0x12, 0x34, 0x56 ) )
window.display()

for iterations in (10, 100, 1000, 5000, 10000, 50000, 100000):
start = time.time()
window.clear( sf.Color( 0x12, 0x34, 0x56 ) )

for loop in range( 0, iterations ):
x, y = random.randint( 0, 500 ), random.randint( 0, 500 )
sprite.set_position( x, y )
window.draw( sprite )

window.display()
print u"%d iterations took %.4f seconds." % (iterations, time.time() - start)

print u"Finished."
time.sleep( 1 )



This is just too bad, writing the wrapper via Boost.Python really felt elegant. :/

Svenstaro

  • Full Member
  • ***
  • Posts: 222
    • View Profile
A little more abstraction
« Reply #9 on: July 22, 2010, 03:05:47 am »
Do you have a C++ example to compare those figures to?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
A little more abstraction
« Reply #10 on: July 22, 2010, 08:42:10 am »
Why don't you use a code generator like SWIG or SIP? You would have the benefits of auto-generated code without the overhead of an API like boost.python.

But after reading the other topic (about naming convensions and exceptions), I don't know if generating the binding automatically would be flexible enough. Changing names would be ok, but for example turning Load functions into constructors throwing an exception may be harder to achieve automatically.
Laurent Gomila - SFML developer

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
A little more abstraction
« Reply #11 on: July 22, 2010, 10:58:21 am »
Quote from: "Svenstaro"
Do you have a C++ example to compare those figures to?

Nope, I saved the pains for that. ;) I could do it, but it's clear that speeds will be much much higher than any Python approach.

Quote
Why don't you use a code generator like SWIG or SIP? You would have the benefits of auto-generated code without the overhead of an API like boost.python.

That's my option 2. The drawback of code generators is that the produced code is always a bit "ugly" and bloated. But still sexier than maintaining pure wrappers to the Python C API.

Quote
But after reading the other topic (about naming convensions and exceptions), I don't know if generating the binding automatically would be flexible enough. Changing names would be ok, but for example turning Load functions into constructors throwing an exception may be harder to achieve automatically.

It is indeed flexible enough. On the one hand SWIG provides a lot of constructs to accomplish such tasks. On the other hand you can still provide your own wrapper functions to get your wanted results (this brings in another call, but it'd normally happen only at not time-critical parts). Another very big advantage is that with SWIG, you don't only have the binding to Python, but also to many other languages.

I've never touched SIP but just checked their website. The fact that it's used for Qt is interesting. :)

Svenstaro:
As you're contributing to PySFML a lot (regarding to the SVN log ;)), I think we should have a little chat or something (remi.k2620 still around? If so, count yourself in ;)). Would be nice if you'd send me a private message.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32504
    • View Profile
    • SFML's website
    • Email
A little more abstraction
« Reply #12 on: July 22, 2010, 11:37:50 am »
Quote
The drawback of code generators is that the produced code is always a bit "ugly" and bloated.

Do we really care about that? ;)
And actually it is not that ugly (at least with SIP), it looks like hand-written code.

Quote
Another very big advantage is that with SWIG, you don't only have the binding to Python, but also to many other languages

Very interesting indeed, but I'm worried about custom code that we may have to add for each language, and about the fact that each language may have a slightly different API.

Quote
I've never touched SIP but just checked their website. The fact that it's used for Qt is interesting.

I think it was made for PyQt and Qt bindings in general, but it looks like generic enough to be used for building any binding :)
Laurent Gomila - SFML developer

Svenstaro

  • Full Member
  • ***
  • Posts: 222
    • View Profile
A little more abstraction
« Reply #13 on: July 22, 2010, 09:10:15 pm »
Quote from: "Tank"
Quote from: "Svenstaro"
Do you have a C++ example to compare those figures to?

Nope, I saved the pains for that. ;) I could do it, but it's clear that speeds will be much much higher than any Python approach.

Actually that should be more for a general approximation of performance. "How bad is this slow down in reality?" "How is PySFML actually doing compared to SFML?"

I mean, as long as the speed is still quick enough for about any practical use then I would clearly go for the easier to write approach.

Quote from: "Tank"

Svenstaro:
As you're contributing to PySFML a lot (regarding to the SVN log ;)), I think we should have a little chat or something (remi.k2620 still around? If so, count yourself in ;)). Would be nice if you'd send me a private message.

Meh, I only made one commit but I'm certainly interested. remi seems to have disappeared, I sent him a PM a few weeks ago and still no answer.

I'm shooting you a PM though I think development should be open.

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
A little more abstraction
« Reply #14 on: July 23, 2010, 02:32:03 am »
Of course! Not that anybody misunderstands my statement: I'd like to talk to you for some coordination stuff, nothing else.

Will contact you tomorrow, thanks for your PM. And regarding to the C++ benchmark: I posted the Python sourcecode; should be quite easy to adept it to C++. ;)