PR# 5608 buffered_... features in EV_RICH_TEXT slow

Problem Report Summary
Submitter: ericbe
Category: EiffelVision
Priority: Medium
Date: 2005/10/17
Class: Bug
Severity: Serious
Number: 5608
Release: 5.6.1218
Confidential: No
Status: Open
Responsible: misterieking
Environment: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.1.4322)
Synopsis: buffered_... features in EV_RICH_TEXT slow

Description
I'm using an EV_RICH_TEXT and `buffered_append' to display some text in color. It works OK but I noticed that despite the "buffered" word in the feature name it took longer than before (when I was not using EV_RICH_TEXT) to display my text in the window.

I made an experiment where I created the RTF string myself before passing it to the widget and I got better performance (see program attached). 

I also tried to colorize the text after it has been displayed to see if it could improve performance (using calls to EV_RICH_TEXT.modify_region) but the performance was even worse.

So my questions are: why is `buffered_append' that slow, and will that be improved or should I keep my implementation where I build the RTF string myself?
To Reproduce
class MAIN_WINDOW

inherit

	EV_TITLED_WINDOW
		redefine
			initialize, is_in_default_state
		end

feature {NONE} -- Initialization

	initialize is
			-- Initialize `Current'.
		local
			font: EV_FONT
			vbox: EV_VERTICAL_BOX
			hbox: EV_HORIZONTAL_BOX
			button: EV_BUTTON
		do
			Precursor {EV_TITLED_WINDOW}
			close_request_actions.extend (agent ((create {EV_ENVIRONMENT}).application).destroy)
			create vbox
			create hbox
			create button
			button.set_text ("Display colored text")
			button.select_actions.extend (agent add_colored_text)
			hbox.extend (button)
			create button
			button.set_text ("Display rtf text")
			button.select_actions.extend (agent add_rtf_text)
			hbox.extend (button)
			vbox.extend (hbox)
			vbox.disable_item_expand (hbox)
			create rich_text
			rich_text.disable_word_wrapping
			vbox.extend (rich_text)
			vbox.enable_item_expand (rich_text)
			extend (vbox)
			create format1
			format1.set_color (create {EV_COLOR}.make_with_rgb (0, 0, 0))
			font := rich_text.font
			font.set_height (12)
			format1.set_font (font)
			create format2
			format2.set_color (create {EV_COLOR}.make_with_rgb (0, 0, 1))
			font := rich_text.font
			font.set_height (12)
			format2.set_font (font)
		end

	add_colored_text is
			--
		local
			l_length: INTEGER
			i: INTEGER
		do
			set_pointer_style ((create {EV_STOCK_PIXMAPS}).wait_cursor)
			rich_text.set_text ("")
			from i := 1 until i > 50_000 loop
				if i \\ 100 = 0 then
					rich_text.buffered_append (i.out, format2)
				else
					rich_text.buffered_append (i.out, format1)
				end
				rich_text.buffered_append (" ", format1)
				if i \\ 5 = 0 then
					rich_text.buffered_append ("%N", format1)
				end
				i := i + 1
			end
			l_length := rich_text.text_length
			rich_text.flush_buffer_to (l_length + 1, l_length + 1)
			set_pointer_style ((create {EV_STOCK_PIXMAPS}).standard_cursor)
		end

	add_rtf_text is
			--
		local
			l_text: STRING
			i: INTEGER
		do
			set_pointer_style ((create {EV_STOCK_PIXMAPS}).wait_cursor)
			create l_text.make (500_000)
			l_text.append_string (k_rtf_header)
			l_text.append_string ("%N\cf1\fs")
			l_text.append_integer (rich_text.font.height_in_points * 2)
			l_text.append_string ("%N")
			from i := 1 until i > 50_000 loop
				if i \\ 100 = 0 then
					l_text.append_string (k_rtf_blue)
					l_text.append_string (i.out)
					l_text.append_string (k_rtf_end)
				else
					l_text.append_string (i.out)
				end
				l_text.append_character (' ')
				if i \\ 5 = 0 then
					l_text.append_string (k_rtf_newline)
				end
				i := i + 1
			end
			l_text.append_string (k_rtf_end)
			rich_text.set_rtf_text (l_text)
			set_pointer_style ((create {EV_STOCK_PIXMAPS}).standard_cursor)
		end

	rich_text: MY_RICH_TEXT
	format1: EV_CHARACTER_FORMAT
	format2: EV_CHARACTER_FORMAT

feature {NONE} -- Implementation

	is_in_default_state: BOOLEAN is
			-- Is `Current' in its default state?
		do
			-- Re-implement if you wish to enable checking
			-- for `Current'.
			Result := True
		end

feature {NONE} -- RTF

	k_rtf_back: STRING is "{\cf1 "
	k_rtf_blue: STRING is "{\cf2 "
	k_rtf_end: STRING is "}"
	k_rtf_newline: STRING is "%N\par "
	k_rtf_tab: STRING is "\tab "
	k_rtf_left_brace: STRING is "\{"
	k_rtf_right_brace: STRING is "\}"
	k_rtf_backslash: STRING is "\\"

	k_newline: STRING is "%N"
	k_tab: STRING is "%T"
	k_left_brace: STRING is "{"
	k_right_brace: STRING is "}"
	k_backslash: STRING is "\"

	k_rtf_header: STRING is "%
%{\rtf1\ansi\ansicpg1252\uc1\deff0\stshfdbch0\stshfloch0\stshfhich0\stshfbi0\deflang1033\deflangfe1033%N%
%{\fonttbl%N%
%	{\f1\froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}%N%
%	{\f0\fmodern\fcharset0\fprq1{\*\panose 02070309020205020404}Courier New;}%N%
%}%N%
%{\colortbl;%N%
%	\red0\green0\blue0;%N%
%	\red0\green0\blue255;%N%
%}%N%
%\tx360\tx720\tx1080\tx1440\tx1800\tx2160\tx2520\tx2880\tx3240\tx3600\tx3960\tx4320%
%"

end
---------------------------------------------------
class MY_RICH_TEXT

inherit

	EV_RICH_TEXT

feature

	set_rtf_text (a_rtf_text: STRING) is
			-- Set `text' with RTF text `a_rtf_text'.
		require
			a_rtf_text_not_void: a_rtf_text /= Void
		local
			l_wel_rich_edit: WEL_RICH_EDIT
			l_stream: WEL_RICH_EDIT_BUFFER_LOADER
		do
			l_wel_rich_edit ?= implementation
			if l_wel_rich_edit /= Void then
				l_wel_rich_edit.set_text ("")
				create l_stream.make (a_rtf_text)
				l_wel_rich_edit.insert_rtf_stream_in (l_stream)
			end
		end

end
Problem Report Interactions
From:ericbe    Date:2005/11/11    Download