Re: [review] [PyKDE] PyQT module size

2005-03-05 Thread Giovanni Bajo
Phil Thompson [EMAIL PROTECTED] wrote:

 I think I'm just going to go with the other users' recommendation of
 nabbing the latest sip and compiling with some different flags with GCC4
 and see if that gets me some quick wins.  My mind is too small and
 fragile to attempt the changes you proposed above without screwing
 things up or causing myself more time than its worth (Thanks just the
 same for the options though) Which is kind of how I view pyqt in general
 - A time saver.

 As I understand it, GCC4 won't give any improvement if you are using the
 latest SIP (although it would be nice to have this confirmed). Thanks to
 Ulli, modules now only export a single symbol - just using the latest SIP
 by itself should give you the improvements.

Yeah, I had missed that. I assume this is being done with a linker script.

The new features of GCC4 are handy if you need to export multiple C++
classes, and you don't want to mention hundreds of mangled names in a linker
script (including vtables, etc.), or manually mark each and every member
function and member variable with a GCC-specific __attribute__. But this is
not the case here.
-- 
Giovanni Bajo

___
PyKDE mailing listPyKDE@mats.imk.fraunhofer.de
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde


Re: [review] [PyKDE] PyQT module size

2005-03-04 Thread Phil Thompson
 I think I'm just going to go with the other users' recommendation of
 nabbing the latest sip and compiling with some different flags with GCC4
 and see if that gets me some quick wins.  My mind is too small and
 fragile to attempt the changes you proposed above without screwing
 things up or causing myself more time than its worth (Thanks just the
 same for the options though) Which is kind of how I view pyqt in general
 - A time saver.

As I understand it, GCC4 won't give any improvement if you are using the
latest SIP (although it would be nice to have this confirmed). Thanks to
Ulli, modules now only export a single symbol - just using the latest SIP
by itself should give you the improvements.

 I do have one last question for you though.  One user seemed to purport,
 and I haven't tested hard enough yet to confirm it, that when two python
 strings are concatenated:

 x = x + y

 That a new string is created, leaving the old reference to x in memory.
 With python's garbage collection as it is, this doesn't seem to be
 correct, but I wanted to ensure there wasn't some special way of
 handling cleanup that I need to take into account.

Often you find that your are keeping an extra reference elsewhere. Use
sys.getrefcount() to check.

Phil

___
PyKDE mailing listPyKDE@mats.imk.fraunhofer.de
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde


C++ data (Re: [PyKDE] PyQT module size)

2005-02-19 Thread Simon Edwards
Hello,

I wrote a version of mem.py in C++, and have put the data side by side in a 
spreadsheet. It appears that a PyQt program more overhead has in terms of 
libraries over C++, roughly 8Mb in this test for me. When running, the memory 
usage pattern seems to mirror the C++ program with perhaps a little bit of 
overhead per object, ~10% (ballpark figure).

What is needed now is some tests that create lots of Qt objects, and then see 
how object creation affects memory usage.

Using Mandrake Linux 10.1, Qt-3.3.3, SIP 4.0.1 (I think, from kdebindings 
3.3.1)

cheers,

-- 
Simon Edwards             | Guarddog Firewall
[EMAIL PROTECTED]       | http://www.simonzone.com/software/
Nijmegen, The Netherlands | ZooTV? You made the right choice.


PyQt_memory_usage.xls
Description: application/msexcel
/*

*/
#include qapplication.h
#include qstringlist.h
#include qpushbutton.h
#include qfile.h

void ProcMem() {
	QStringList lines;
	QFile file(/proc/self/status);

	if(file.open( IO_ReadOnly ) ) {
		QTextStream stream( file );
		QString line;
		while ( !stream.atEnd() ) {
			line = stream.readLine(); // line of text excluding '\n
			if(line.startsWith(V)) {
printf( %s\n, line.latin1() );
			}
			lines += line;
		}
	file.close();
	}
} 

int main( int argc, char ** argv ) {
	printf(\nInitial values\n);
	ProcMem();

	printf(\nCreate QApplication\n);
	QApplication *qapp = new QApplication( argc, argv );
	ProcMem();

	printf(\nCreate Pushbutton\n);
	QPushButton *b = new QPushButton(Hello World, 0);
	qapp-setMainWidget(b);
	ProcMem();

	printf(\nShow Pushbutton\n);
	b-show();
	ProcMem();

	printf(\nConnect Pushbutton signal\n);
	qapp-connect(b, SIGNAL(clicked()), qapp, SLOT(quit()));
	ProcMem();

	printf(Enter Mainloop\n);
	qapp-exec();
	ProcMem();

	printf(Mainloop finished\n);
	ProcMem();

	printf(Delete Pushbutton\n);
	delete b;
	ProcMem();

	printf(Delete Application\n);
	delete qapp;
	ProcMem();

	return 0;
}
___
PyKDE mailing listPyKDE@mats.imk.fraunhofer.de
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde


[PyKDE] PyQT module size

2005-02-18 Thread Brian Thomason
We've been using PyQT/PyKDE here at Linspire for some time now to 
develop a handful of applications.  One of these is Lsongs, and it has 
grown quite large and has a very large memory footprint.  We're trying 
to reduce this a bit in various ways (switching to gstreamer from 
libxine for instance) and I was curious if there was a way to reduce the 
footprint size of pyqt/pykde.  The shared object files themselves are 
quite large - Larger than their C++ counterparts. 

I'm totally ignorant on python bindings so this may just be the way it 
is and that's fine.  Just curious if there's a way to shrink these 
down a bit.

Thanks,
-Brian
--
This message contains information which may be confidential and privileged. Unless you are the 
addressee (or authorized to receive for the addressee), you may not use, copy or disclose to anyone 
the message or any information contained in the message. If you have received the message in error, 
please advise the sender and delete the message.  Thank you.

___
PyKDE mailing listPyKDE@mats.imk.fraunhofer.de
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde


Re: [PyKDE] PyQT module size

2005-02-18 Thread Rob Knapp
On Thu, 2005-02-17 at 11:47 -0800, Brian Thomason wrote:
 We've been using PyQT/PyKDE here at Linspire for some time now to 
 develop a handful of applications.  One of these is Lsongs, and it has 
 grown quite large and has a very large memory footprint.  We're trying 
 to reduce this a bit in various ways (switching to gstreamer from 
 libxine for instance) and I was curious if there was a way to reduce the 
 footprint size of pyqt/pykde.  The shared object files themselves are 
 quite large - Larger than their C++ counterparts. 

I fought this battle while at a previous position (admittedly on
windows, not linux).  The only solution I could find was to compile QT
with the absolute minimum set of classes required for my application.
This got QT down to about 2Megs and PyQT down to about 3.5 or so. 

I can't remember the exact figures, but it doesn't matter since you are
using a different compiler.  I do recall that it was more than half for
me, but I wasn't using several large modules.  The other horrible hack
you can do to change this is to manually edit the main sip file and
remove (or comment out) the includes for the classes you don't need.
This gives you a fully functional QT, but a hobbled pyqt.  (And then I
would suggest changing the name of qt.pyd to linQt.pyd or some such so
that users can install their own full version of py qt)

We also hit memory foot print issues, and the first thing I will say is
watch your python strings!  string A + string B  creates a new string,
so concatenating using the + operator uses a lot more memory than you
think.  Once you've done that, look on the web for options on optimizing
memory with python.  There are plenty of resources.  

If you are still having memory problems, the only thing I can suggest
(and this is what we did), is explictly delete as many variables as you
can.  This also can help.  

If you get _really_ desperate, you can force garbage collection in a
seperate (python) thread, but that lead to some stability issues for me.

Finally, if you really are at the end of the loop, if there is a call
like win32's SetWorkingSetSize that writes unused objects to virtual
memory, you can sprinkle that at strategic locations or even in a
background loop. (Probably need to expose whatever call it would be.)
Of course there is a pretty large performance hit here, but it can be
very effective in freeing up physical ram for other apps.  It also isn't
cross-platform, but considering that you work for a linux company, I
doubt that is the end of the world. :)

In my situation (a video conferencing suite), this was very useful as my
UI application's performance was virtually irrelevant as along as the
video and networking apps were running well.  (long story, everything
was in a seperate app so if one part failed, the conference could
continue).

None of this is probably what you want to hear.  AFAICT, there is no
magic bullet that shrinks PyQTs memory down.  What I can say if applying
everything except the SetWorkingSetSize, we went from about 50 Megs
while in conference to about 20 Megs while in conference.  We could have
saved more in a couple of areas specific to our application (the
skinning engine, and our interactions with zip files), but money ran out
before we could do that.

 I'm totally ignorant on python bindings so this may just be the way it 
 is and that's fine.  Just curious if there's a way to shrink these 
 down a bit.
 
 Thanks,
 
 -Brian
 --
 
 This message contains information which may be confidential and privileged. 
 Unless you are the 
 addressee (or authorized to receive for the addressee), you may not use, copy 
 or disclose to anyone 
 the message or any information contained in the message. If you have received 
 the message in error, 
 please advise the sender and delete the message.  Thank you.
 
 ___
 PyKDE mailing listPyKDE@mats.imk.fraunhofer.de
 http://mats.imk.fraunhofer.de/mailman/listinfo/pykde
-- 
---
Rob Myddrin Knapp
[EMAIL PROTECTED]
http://www.myddrin.com

___
PyKDE mailing listPyKDE@mats.imk.fraunhofer.de
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde


Re: [PyKDE] PyQT module size

2005-02-18 Thread Giovanni Bajo
Brian Thomason [EMAIL PROTECTED] wrote:

 We've been using PyQT/PyKDE here at Linspire for some time now to
 develop a handful of applications.  One of these is Lsongs, and it has
 grown quite large and has a very large memory footprint.  We're trying
 to reduce this a bit in various ways (switching to gstreamer from
 libxine for instance) and I was curious if there was a way to reduce the
 footprint size of pyqt/pykde.  The shared object files themselves are
 quite large - Larger than their C++ counterparts.

 I'm totally ignorant on python bindings so this may just be the way it
 is and that's fine.  Just curious if there's a way to shrink these
 down a bit.

One low-hanging fruit could be recompiling them through the upcoming GCC 4
using the new -fvisibility=hidden -fvisibility-inline-hidden options. By
making only the needed symbols visibile (which AFAIK it is just one symbol
for a Python extension module), the shared object size will reduce somehow,
will be much much faster to load and will also be optimized better. See
http://gcc.gnu.org/gcc-4.0/changes.html and
http://www.nedprod.com/programs/gccvisibility.html for further reference.
I'm sure there is already some infrastructure for this, as the windows
version of qt.pyd exports just one visible symbol.
-- 
Giovanni Bajo

___
PyKDE mailing listPyKDE@mats.imk.fraunhofer.de
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde


Re: [PyKDE] PyQT module size

2005-02-18 Thread Hans-Peter Jansen
On Thursday 17 February 2005 20:47, Brian Thomason wrote:
 We've been using PyQT/PyKDE here at Linspire for some time now to
 develop a handful of applications.  One of these is Lsongs, and it
 has grown quite large and has a very large memory footprint.  We're
 trying to reduce this a bit in various ways (switching to gstreamer
 from libxine for instance) and I was curious if there was a way to
 reduce the footprint size of pyqt/pykde.  The shared object files
 themselves are quite large - Larger than their C++ counterparts.

Since this is an actual concern of mine, too, I ran some tests with 
the attached script, mainly to explore the impact of importing:

from qt import Q...

versus 

from qt import * 

To conclude, it is quite small, but see yourself:
On SuSE 9.0, 2.4.21-273-athlon:
sip version: 4.1.1
Qt version: 3.2.1
PyQt version: 3.13
the difference is about 80k :-(

VmSize:63072 kB
VmLck: 0 kB
VmRSS: 16152 kB
VmData: 4380 kB
VmStk:44 kB
VmExe: 4 kB
VmLib: 21640 kB

VmSize:63108 kB
VmLck: 0 kB
VmRSS: 16236 kB
VmData: 4376 kB
VmStk:44 kB
VmExe: 4 kB
VmLib: 21676 kB

On SuSE 9.2, 2.6.8-24.11:
sip version: 4.0.1
Qt version: 3.3.3
PyQt version: 3.12 (all from kdebindings3-python-3.3.0-13):

VmSize:26216 kB
VmLck: 0 kB
VmRSS: 14148 kB
VmData: 4336 kB
VmStk:56 kB
VmExe: 2 kB
VmLib: 19606 kB

VmSize:26352 kB
VmLck: 0 kB
VmRSS: 14156 kB
VmData: 4472 kB
VmStk:56 kB
VmExe: 2 kB
VmLib: 19606 kB

If some kind soul could explain the huge difference in VmSize between 
2.4 and 2.6 from /proc/pid/status, I would feel much better.. 

Pete
import sys
if len(sys.argv)  1 and sys.argv[1] == '-a':
from qt import *
else:
from qt import QApplication, QPushButton, SIGNAL, qApp
a = QApplication(sys.argv)
b = QPushButton(Hello World, None)
a.setMainWidget(b)
b.show()
a.connect(b, SIGNAL(clicked()), qApp.quit)
a.exec_loop()

___
PyKDE mailing listPyKDE@mats.imk.fraunhofer.de
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde


Re: [PyKDE] PyQT module size

2005-02-18 Thread Hans-Peter Jansen
On Friday 18 February 2005 18:00, Hans-Peter Jansen wrote:

and here's a more detailed comparison from the two:

9.0:   9.2:
sip version: 4.1.1 sip version: 4.0.1
Qt version: 3.2.1  Qt version: 3.3.3
PyQt version: 3.13 PyQt version: 3.12
Python: 2.3Python: 2.3.4

Initial Values Initial Values
VmSize: 4928 kBVmSize: 4276 kB
VmData: 1404 kBVmData:  852 kB
VmRSS:  2772 kBVmRSS:  2508 kB
VmLib:  2984 kBVmLib:  2886 kB
Import qt  Import qt
VmSize:22464 kB17536 kBVmSize:21652 kB17376 kB
VmData: 1584 kB  180 kBVmData: 1200 kB  348 kB
VmRSS:  9336 kB 6564 kBVmRSS:  8252 kB 5744 kB
VmLib: 19552 kB16568 kBVmLib: 19190 kB16304 kB
Create Application Create Application
VmSize:60972 kB38508 kBVmSize:23912 kB 2260 kB
VmData: 2692 kB 1108 kBVmData: 2492 kB 1292 kB
VmRSS: 13656 kB 4320 kBVmRSS: 11020 kB 2768 kB
VmLib: 21252 kB 1700 kBVmLib: 19230 kB   40 kB
Create Pushbutton  Create Pushbutton
VmSize:60972 kB0 kBVmSize:23904 kB   -8 kB
VmData: 2692 kB0 kBVmData: 2484 kB   -8 kB
VmRSS: 13824 kB  168 kBVmRSS: 11188 kB  168 kB
VmLib: 21252 kB0 kBVmLib: 19230 kB0 kB
Show PushbuttonShow Pushbutton
VmSize:62964 kB 1992 kBVmSize:26356 kB 2452 kB
VmData: 4272 kB 1580 kBVmData: 4476 kB 1992 kB
VmRSS: 15896 kB 2072 kBVmRSS: 13836 kB 2648 kB
VmLib: 21640 kB  388 kBVmLib: 19606 kB  376 kB
Connect Pushbutton signal  Connect Pushbutton signal
VmSize:62964 kB0 kBVmSize:26356 kB0 kB
VmData: 4272 kB0 kBVmData: 4476 kB0 kB
VmRSS: 15924 kB   28 kBVmRSS: 13860 kB   24 kB
VmLib: 21640 kB0 kBVmLib: 19606 kB0 kB
Enter Mainloop Enter Mainloop
VmSize:63136 kB  172 kBVmSize:26356 kB0 kB
VmData: 4404 kB  132 kBVmData: 4476 kB0 kB
VmRSS: 16260 kB  336 kBVmRSS: 14196 kB  336 kB
VmLib: 21676 kB   36 kBVmLib: 19606 kB0 kB
Mainloop finished  Mainloop finished
VmSize:63136 kB0 kBVmSize:26356 kB0 kB
VmData: 4404 kB0 kBVmData: 4476 kB0 kB
VmRSS: 16260 kB0 kBVmRSS: 14196 kB0 kB
VmLib: 21676 kB0 kBVmLib: 19606 kB0 kB
Delete Pushbutton  Delete Pushbutton
VmSize:63128 kB   -8 kBVmSize:26356 kB0 kB
VmData: 4396 kB   -8 kBVmData: 4476 kB0 kB
VmRSS: 16260 kB0 kBVmRSS: 14200 kB4 kB
VmLib: 21676 kB0 kBVmLib: 19606 kB0 kB
Delete Application Delete Application
VmSize:38132 kB   -24996 kBVmSize:25688 kB -668 kB
VmData: 4396 kB0 kBVmData: 4268 kB -208 kB
VmRSS: 16028 kB -232 kBVmRSS: 13848 kB -352 kB
VmLib: 21288 kB -388 kBVmLib: 19230 kB -376 kB

Funny are the tremendous movements in QApplication ctor/dtor on the 
left. 

Pete
#! /usr/bin/env python

import sys, os

class ProcMem:
def __init__(self):
self.pid = os.getpid()
self.initial = self.getValues()
self.showValues(self.initial)

def getValues(self):
val = {}
fp = open(/proc/%s/status % self.pid, r)
for l in fp:
if l.startswith(Vm):
k, v = l.split()[:2]
if k in (VmData:;, VmLib:, VmRSS:, VmSize:):
val[k] = int(v)
return val

def showValues(self, val, val2 = None):
for k in VmSize:, VmData:;, VmRSS:, VmLib::
if val2:
print %-7s %8s kB %8s kB % (k, val[k], val[k]-val2[k])
else:
print %-7s %8s kB % (k, val[k])

def diffValues(self):
val = self.getValues()
self.showValues(val, self.initial)
self.initial = val

print Initial Values
pm = ProcMem()

print Import qt
import qt
pm.diffValues()

print Create Application
a = qt.QApplication(sys.argv)
pm.diffValues()

print Create Pushbutton
b = qt.QPushButton(Hello World, None)
a.setMainWidget(b)
pm.diffValues()

print Show Pushbutton
b.show()
pm.diffValues()

print Connect Pushbutton signal
a.connect(b, qt.SIGNAL(clicked()), qt.qApp.quit)
pm.diffValues()

print Enter Mainloop
a.exec_loop()
pm.diffValues()

print Mainloop finished
pm.diffValues()

print Delete Pushbutton
del b

Re: [review] [PyKDE] PyQT module size

2005-02-18 Thread Jim Bublitz
On Friday 18 February 2005 06:38, Brian Thomason wrote:
 We've been using PyQT/PyKDE here at Linspire for some time now to
 develop a handful of applications.  One of these is Lsongs, and it has
 grown quite large and has a very large memory footprint.  We're trying
 to reduce this a bit in various ways (switching to gstreamer from
 libxine for instance) and I was curious if there was a way to reduce the
 footprint size of pyqt/pykde.  The shared object files themselves are
 quite large - Larger than their C++ counterparts.

 I'm totally ignorant on python bindings so this may just be the way it
 is and that's fine.  Just curious if there's a way to shrink these
 down a bit.

Short answer: no.

Long answer: I agree that if you look at the module sizes as they sit on disk, 
it looks pretty horrendous. A simple KDE plugin program written using PyKDE 
looks like it will use something in the 15-20MB range if you add up the .so 
sizes. In reality though, the actual memory usage, especially since KDE is 
already running and its and Qt's libs are already loaded, isn't all that bad. 

I seem to recall the actual overhead for a fairly large program using several 
PyQt modules and 5 or 6 PyKDE modules  is somewhere around 6-8MB according to 
'free'. Another way to look at it is that the *first* app has a lot of 
overhead, but each successive PyQt/PyKDE app has very little - use them 
more :) Still another way to view it is that getting to QApplication or 
KApplication is very expensive, but everything after that is really cheap.

Most of the code is pretty much a fixed amount of overhead per method and 
that's written very efficiently by sip. The tradeoff then becomes size of 
code vs. completeness of code - ie, the only way to make PyQt or PyKDE 
smaller is by throwing out methods and classes. Throwing out methods is 
possible; throwing out classes can eventually become a dependency nightmare.

In either case, it's pretty hard to take a general purpose development system 
and predict what users will find useful or necessary down the road, so the 
philosophy (at least for PyKDE) has been to include everything that can 
possibly be included. Another solution would be to make more and smaller 
modules, but then it becomes a problem for users to figure out which module 
contains which classes and methods (and it's not an easy task for us either).

I've discussed this in the past, and the conclusion is usually well, nobody 
ever complains about it - this is literally (to my knowledge) the first 
complaint we've ever had. It's a question of how much you're willing to pay 
for the convenience of writing Qt/KDE code in Python, and it seems like the 
market price in KB is pretty high (and memory is pretty cheap).

There are ways that a custom set of bindings could be developed for your 
applications that only expose the methods/classes from PyQt/PyKDE that you 
really need. It would involve writing a custom set of C++ wrappers for the 
PyQt/PyKDE APIs and then binding those. Depending on what you need, that 
could be as small as a few hundred K for everything. For an application of 
any complexity (eg menus/toolbar/statusbar and a selection of various 
widgets, std file dialogs, etc) it might turn out to be quite a bit of work 
though, and the resulting names wouldn't look like Qt/KDE anymore.

You could also try taking the PyQt/PyKDE and throwing stuff out - that might 
save 30% or so, depending on what you need to leave in. However, when you do 
a menu using actions (esp standard actions) in KDE, for example, there's a 
lot of underlying code that you never see that PyKDE needs to bind (that's 
what a wrapper can get rid of).

Lastly, it seems to me there's probably a different approach that could access 
the Qt/KDE C++ libs without the per method overhead and be quite small, but 
it's likely to execute considerably slower and be pretty complex, esp when 
you get into things like virtual method overloading or mapping types between 
Python and C/C++. The latter might even destroy the initial size advantage. 
I'm also not sure if that would be possible if the symbols are stripped from 
the .so libs being accessed - don't know enough about .so structure to really 
say.

Jim

___
PyKDE mailing listPyKDE@mats.imk.fraunhofer.de
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde