http://www.ezdoum.com/stories.php?story=07/10/10/5189338
1. 重新编译glib
CFLAGS="-pg -g" ./autogen.sh --disable-gtk-doc --enable-debug=minimum \ --prefix=/your install path --disable-shared
make; make install
2. 写个测试代码
#define REPEATS 100000 #include <glib.h> #include <glib-object.h> /*************************/ #define TYPE_TEST_OBJECT (test_object_get_type ()) #define TEST_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ TYPE_TEST_OBJECT, TestObject)) #define IS_TEST_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ TYPE_TEST_OBJECT)) typedef struct _TestObject TestObject; typedef struct _TestObjectClass TestObjectClass; struct _TestObject { GObject parent_instance; gint foo; gchar *bar; }; struct _TestObjectClass { GObjectClass parent_class; }; GType test_object_get_type (void) G_GNUC_CONST; TestObject *test_object_new (void); enum { PROP_0, PROP_FOO, PROP_BAR }; static void test_object_class_init (TestObjectClass *klass); static void test_object_init (TestObject *object); static void test_object_finalize (GObject *object); static void test_object_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec); static void test_object_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec); static GObjectClass *parent_class = NULL; GType test_object_get_type (void) { static GType test_object_type = 0; if (!test_object_type) { static const GTypeInfo test_object_info = { sizeof (TestObjectClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) test_object_class_init, NULL, /* class_finalize */ NULL, /* class_data */ sizeof (TestObject), 0, /* n_preallocs */ (GInstanceInitFunc) test_object_init, }; test_object_type = g_type_register_static (G_TYPE_OBJECT, "TestObject", &test_object_info, 0); } return test_object_type; } static void test_object_class_init (TestObjectClass *klass) { GObjectClass *object_class; GParamSpec *param_spec; object_class = G_OBJECT_CLASS (klass); parent_class = g_type_class_peek_parent (klass); object_class->set_property = test_object_set_property; object_class->get_property = test_object_get_property; param_spec = g_param_spec_string ("bar", NULL, NULL, NULL, G_PARAM_READABLE | G_PARAM_WRITABLE #ifdef MAKE_IT_SLOW_2 | G_PARAM_CONSTRUCT_ONLY #endif ); g_object_class_install_property (object_class, PROP_BAR, param_spec); param_spec = g_param_spec_int ("foo", NULL, NULL, G_MININT, G_MAXINT, 0, G_PARAM_READABLE | G_PARAM_WRITABLE #ifdef MAKE_IT_SLOW_2 | G_PARAM_CONSTRUCT_ONLY #endif ); g_object_class_install_property (object_class, PROP_FOO, param_spec); object_class->finalize = test_object_finalize; } static void test_object_init (TestObject *object) { object->bar = NULL; object->foo = 0; } static void test_object_finalize (GObject *object) { TestObject *obj; obj = (TestObject *) (object); g_free (obj->bar); if (G_OBJECT_CLASS (parent_class)->finalize) G_OBJECT_CLASS (parent_class)->finalize (object); } static void test_object_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { TestObject *test_object; test_object = TEST_OBJECT (object); switch (property_id) { case PROP_FOO: test_object->foo = g_value_get_int (value); break; case PROP_BAR: g_free (test_object->bar); test_object->bar = g_value_dup_string (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void test_object_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { TestObject *test_object; test_object = TEST_OBJECT (object); switch (property_id) { case PROP_BAR: g_value_set_string (value, test_object->bar); break; case PROP_FOO: g_value_set_int (value, test_object->foo); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } TestObject * test_object_new (void) { #ifdef MAKE_IT_SLOW_1 return TEST_OBJECT (g_object_new (test_object_get_type (), "foo", 5, "bar", "blah", NULL)); #else TestObject *obj = TEST_OBJECT (g_object_new (test_object_get_type (), NULL)); obj->foo = 5; obj->bar = g_strdup ("blah"); return obj; #endif } /*************************/ int main (int argc, char *argv[]) { GTimeVal start, end; int i; TestObject *obj[REPEATS]; g_type_init_with_debug_flags (G_TYPE_DEBUG_NONE); test_object_new (); g_get_current_time (&start); for (i = 0; i < REPEATS; i++) obj[i] = test_object_new (); g_get_current_time (&end); if (end.tv_usec - start.tv_usec < 0) end.tv_sec--, end.tv_usec += 1000000; g_print ("loop %d, %ld.%06ld sec\n", REPEATS, (end.tv_sec - start.tv_sec), (end.tv_usec - start.tv_usec)); return 0; }
3. 编译测试代码
Then try: gcc -Wall -pg -g gobject-test.c -o gobject-test \ `pkg-config --cflags --libs gobject-2.0` vs. gcc -DMAKE_IT_SLOW_1 -Wall -pg -g gobject-test.c -o gobject-test \ `pkg-config --cflags gobject-2.0` `pkg-config --libs gobject-2.0` or gcc -DMAKE_IT_SLOW_2 -Wall -pg -g gobject-test.c -o gobject-test \ `pkg-config --cflags gobject-2.0` `pkg-config --libs gobject-2.0`
4. 用gprof看看:
gprof -b ./gobject-test Flat profile: Each sample counts as 0.01 seconds. no time accumulated % cumulative self self total time seconds seconds calls Ts/call Ts/call name 0.00 0.00 0.00 200002 0.00 0.00 test_object_get_type 0.00 0.00 0.00 100001 0.00 0.00 test_object_new Call graph granularity: each sample hit covers 2 byte(s) no time propagated index % time self children called name 0.00 0.00 200002/200002 test_object_new [2] [1] 0.0 0.00 0.00 200002 test_object_get_type [1] ----------------------------------------------- 0.00 0.00 100001/100001 main [8] [2] 0.0 0.00 0.00 100001 test_object_new [2] 0.00 0.00 200002/200002 test_object_get_type [1] ----------------------------------------------- Index by function name [1] test_object_get_type [2] test_object_new
build again:
gcc -DMAKE_IT_SLOW_1 -Wall -pg -g gobject-test.c -o gobject-test `pkg-config --cflags --libs gobject-2.0`
gprof -b ./gobject-test Flat profile: Each sample counts as 0.01 seconds. % cumulative self self total time seconds seconds calls ns/call ns/call name 50.12 0.01 0.01 400004 12.53 12.53 test_object_get_type 50.12 0.01 0.01 frame_dummy 0.00 0.01 0.00 100001 0.00 25.06 test_object_new Call graph granularity: each sample hit covers 2 byte(s) for 99.77% of 0.01 seconds index % time self children called name 0.00 0.00 200002/400004 test_object_set_property [5] 0.00 0.00 200002/400004 test_object_new [3] [1] 50.0 0.01 0.00 400004 test_object_get_type [1] ----------------------------------------------- <spontaneous> [2] 50.0 0.01 0.00 frame_dummy [2] ----------------------------------------------- 0.00 0.00 100001/100001 main [4] [3] 25.0 0.00 0.00 100001 test_object_new [3] 0.00 0.00 200002/400004 test_object_get_type [1] ----------------------------------------------- <spontaneous> [4] 25.0 0.00 0.00 main [4] 0.00 0.00 100001/100001 test_object_new [3] ----------------------------------------------- <spontaneous> [5] 25.0 0.00 0.00 test_object_set_property [5] 0.00 0.00 200002/400004 test_object_get_type [1] ----------------------------------------------- Index by function name [2] frame_dummy [1] test_object_get_type [3] test_object_new
build again:
gcc -DMAKE_IT_SLOW_2 -Wall -pg -g gobject-test.c -o gobject-test `pkg-config --cflags --libs gobject-2.0`
gprof -b ./gobject-test Flat profile: Each sample counts as 0.01 seconds. no time accumulated % cumulative self self total time seconds seconds calls Ts/call Ts/call name 0.00 0.00 0.00 400004 0.00 0.00 test_object_get_type 0.00 0.00 0.00 100001 0.00 0.00 test_object_new Call graph granularity: each sample hit covers 2 byte(s) no time propagated index % time self children called name 0.00 0.00 200002/400004 test_object_set_property [14] 0.00 0.00 200002/400004 test_object_new [2] [1] 0.0 0.00 0.00 400004 test_object_get_type [1] ----------------------------------------------- 0.00 0.00 100001/100001 main [8] [2] 0.0 0.00 0.00 100001 test_object_new [2] 0.00 0.00 200002/400004 test_object_get_type [1] ----------------------------------------------- Index by function name [1] test_object_get_type [2] test_object_new