Re: GtkText vs GtkTextView



Raymond Wan <rwan cs mu oz au> writes:
> 
> 	I haven't tried v1.3 of GTK+ yet, but I'm wondering if I should.
> What I'm using is a GtkText that's holding a lot of text...like megabytes
> of text and I don't mind switching to v1.3, even if it's just a
> pre-release of 2.0 .  My program seems to be using a lot of memory and I'm
> wondering if, generally speaking, should a GtkTextView use more or less
> memory?  If less, about how much?  75%?  50?  any approx. number would be
> great.
> 
> 	I read a bit of the documentation, but as I don't know what
> quality of a GtkText that's making it use so much memory, I don't know if
> a GtkTextView is an improvement.  Thank you!
> 

If I put 10 megs of text in a GtkText, then I get about 13 megs of
memory usage for the application on startup, including 2 megs shared,
so close enough to 10 megs allocated to be lost in the noise.  However
if you start scrolling around this goes up to 20 something megs, I
think GtkText has some kind of scroll cache to try to work around
performance problems. If you start typing in the GtkText it goes up to
40 megs or so, so there must be some other cache for that.

GtkText takes quite a while to come onscreen, and is sluggish the
first time you do things (like scroll or type) since it has nothing
cached.

GtkTextView uses something like 23 megs to display the 10 megs of
text. It comes onscreen instantly and scrolling and editing are fast
the first time you do them, due to the use of an intelligent data
structure and incremental word-wrap/scroll calculation. There is some
sluggishness while incremental reflow is going on, we could probably
tune that better.

So anyhow, you could say 23 megs for text view vs. 40 for GtkText, but
these numbers can be affected by any number of factors; text view will
use more memory per character if you use shorter lines because it has
per-line overhead, and it will also use more memory per-character if
you use text attributes such as colors in a fine-grained way. That is,
if you have an entirely blue buffer, it can store that information
with two small markers at either end; but if you turn blue on and off
every other word, it will need a marker for every on-off toggle. So
you get a lot more memory usage. If you make lines really long,
TextView will have a good bit less memory overhead, but will start to
have performance issues eventually.

No doubt GtkText has its own odd quirks like this.

The two widgets aren't all that comparable really; text view is doing
a lot more work to support i18n and it has a lot more features as well.

Appended a program you can play with.

Havoc

#define GTK_ENABLE_BROKEN
#include <gtk/gtk.h>
#include <string.h>

/* 1024 bytes in a K, 1024 K in a megabyte, 10 megabytes */
#define LOTS_OF_CHARS (1024*1024*10) 

static gchar* big_string;

static GtkWidget*
create_text (void)
{
  GtkWidget *text;

  text = gtk_text_new (NULL, NULL);

  gtk_text_insert (GTK_TEXT (text),
                   NULL, NULL, NULL,
                   big_string, -1);

  gtk_text_set_editable (GTK_TEXT (text), TRUE);
  
  return text;
}

static GtkWidget*
create_text_view (void)
{
  GtkWidget *text_view;

  text_view = gtk_text_view_new ();

  gtk_text_buffer_set_text (gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view)),
                            big_string, -1);

  return text_view;
}

int
main (int argc, char **argv)
{
  GtkWidget *t;
  GtkWidget *window;
  GtkWidget *sw;
  int i;
  int len;
  const char* line = "Hi this is a line of text, perhaps a fairly typical line of text. Here is a second sentence.\n";
  
  gtk_init (&argc, &argv);

  big_string = g_malloc (LOTS_OF_CHARS);
  
  len = strlen (line);
  i = 0;
  while (i < LOTS_OF_CHARS)
    {
      if ((i + len) >= LOTS_OF_CHARS)
        big_string[i] = '\0';
      else
        strcpy (&big_string[i], line);
      
      i += len;
    }

  /* change this line to create_text() for comparison */  
  t = create_text_view ();

  g_free (big_string);
  
  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

  sw = gtk_scrolled_window_new (NULL, NULL);

  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
                                  GTK_POLICY_AUTOMATIC,
                                  GTK_POLICY_AUTOMATIC);

  gtk_container_add (GTK_CONTAINER (window), sw);

  gtk_container_add (GTK_CONTAINER (sw), t);

  gtk_window_set_default_size (GTK_WINDOW (window), 400, 400);
  
  gtk_widget_show_all (window);

  gtk_main ();

  return 0;
}








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