Re: Mixing XS with Gtk2::TreeStore




On Dec 27, 2008, at 12:19 PM, Emmanuel Rodriguez wrote:

On Sat, Dec 27, 2008 at 4:14 PM, muppet <scott asofyet org> wrote:

On Dec 27, 2008, at 6:41 AM, Emmanuel Rodriguez wrote:


Stop. Custom XS should be a last resort, as it ratchets up the difficulty of maintaining and deploying your application, and is often unnecessary.
Let's do some sanity checks first:

Let me present more deeply the problem. I have a Perl application that
displays an XML document with both source code syntax highlighting and
a DOM tree view. For now the problem I have is showing the DOM tree in
the tree view. For the moment, I'm using a TreeStore because there are
many examples showing how to work with a TreeStore. Populating the
TreeStore with the DOM tree is my current bottleneck. The application
is based on XML::LibXML which in turn is using libxml2. So the there's
already a quite decent data model: XML::LibXML::Document.

The slowness is due to the nature of XML::LibXML where each node and
field access is performed through XS. A small document of 400K can
very easily return over 170_000 DOM nodes. Walking such a tree in Perl
is slow (about 0.5sec) when combining it with the operations of a
TreeStore it takes 1.2 sec. Now imagine loading a 20 Megs document...

Alright, this is a different beast from how i interpreted your original message. Context helps. :-)

So, your current design is to mirror the DOM in the TreeStore by holding a reference to each element in the corresponding node in the tree.

Two approaches come to mind:

x) Create a custom TreeModel implementation that directly accesses the DOM. With some caching you could avoid having to walk the DOM on each access, at the expense of memory, but it's unclear whether this would actually be more efficient than letting TreeStore do that caching work.

y) Glue the DOM and TreeStore together in C code as a custom subclass of TreeStore (or possibly a custom TreeModel, as above, but in C), and create a perl binding for that object.


I think that something like y) was what you were initially trying to do, correct? However, it sounds like you were still creating the objects in perl and trying to implement only the bare minimum, the populate function, in C.


sub create_model {
        my $model = Gtk2::TreeStore->new(
                'Glib::Scalar', # An instance to XML::LibXML::Element
                'Glib::String', # The name of the Element
        );
}

There it is -- the first column is 'Glib::Scalar', which is a generic wrapper for a perl SV. Down in C, you'll see that as an SV. What's inside depends on what you loaded into it. You can't just assume it's a pointer. In fact, since XML::LibXML also wraps stuff up in XS goo, you don't really know for sure how to get to the juicy C pointer inside without scrubbing through the XML::LibXML source. I don't know if they export helper functions in the vein of gtk2-perl's gperl_get_object(), but you'll have to do some research.

This marshaling difficulty is one reason that i would recommend actually writing the whole glue thing up as a GObject in C, and then binding that GObject to perl, instead of trying to do only the populate function. That way, you feed in one XML::LibXML object from perl, and everything else happens in C.


Is there an example on how to implement a custom TreeModel?

I think the list archives will help most. The iters are the biggest stumbling blocks in perl, thanks to how the C api works. For what you're doing, i think i've talked myself into thinking you do, indeed, want to do the work in C.

GTK+ 2.0 Tree View Tutorial
http://scentric.net/tutorial/

leveraging GtkTreeModel
http://davyd.livejournal.com/252351.html



Your stack trace indicates that you *are* adding Perl data types to your tree. Did you create your store with a column type of 'Glib::Scalar'?

Yes the TreeStore has slot for passing the XML::LibXML::Node that's
been displayed in the TreeView. I didn't realized that I had to pass
an SV* there. I was trying to pass a simple C pointer and expected it
to be magically transformed to a Perl type!

Hehe, magic takes work.  ;-)


--
The one difference between Dali and a crazy man is very simple: Dali is not crazy at all.
  -- Salvador Dali





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]