Hi,

Julien Muchembled learn me how to record stdin and then replay it:
   tee events|program  # record
   program < events
Using that, I'm able to do good benchmark. Something _necessary_ to work on 
optimization.

So one big problem of urwid in UTF-8 is that urwid convert Unicode string to 
UTF-8 and then reconvert them to Unicode... It's slow and useless.

The problem is in Canvas class. The attached patch is a proposition to fix the 
problem (double conversion). The idea is to store text encoded for the 
terminal (UTF-8) in Canvas.text but also to keep the Unicode version in 
Canvas.unitext.

Instead of "for ut in unitext: ..." we may use:
if unitext:
   ...
else:
   for t in text:
      t = unicode(t, charset)
      ...
^^ convert to unicode here avoid many slow functions

Don't apply my patch! It's just an example to show the problem. With my patch, 
a UTF-8 terminal and with a program (hachoir-urwid) speaking full-Unicode: 
the program runs 2 times faster (8 seconds => 4 seconds) ;-) It's not 
an "optimization", it's a fix urwid code :)

===

Would it be possible to use spaces in urwid code because I hate TAB! PEP 8 
propose "4 spaces per indentation level":
   http://www.python.org/dev/peps/pep-0008/

===

Where/How can I download urwid by subversion?

Haypo
-- 
Victor Stinner
http://hachoir.org/
diff -urb urwid-0.9.7.1/urwid/canvas.py urwid-unicode/urwid/canvas.py
--- urwid-0.9.7.1/urwid/canvas.py	2006-10-09 17:18:35.000000000 +0200
+++ urwid-unicode/urwid/canvas.py	2006-12-31 01:22:48.000000000 +0100
@@ -35,7 +35,7 @@
 	class for storing rendered text and attributes
 	"""
 	def __init__(self,text = None,attr = None, cs = None, 
-		cursor = None, maxcol=None):
+		cursor = None, maxcol=None, unitext=None):
 		"""
 		text -- list of strings, one for each line
 		attr -- list of run length encoded attributes for text
@@ -46,10 +46,8 @@
 		if text == None: 
 			text = []
 		widths = []
-		for t in text:
-			if type(t) != type(""):
-				raise CanvasError("Canvas text must be plain strings encoded in the screen's encoding", `text`)
-			widths.append( calc_width( t, 0, len(t)) )
+                for ut in unitext:
+                        widths.append( calc_width( ut, 0, len(ut)) )
 
 		if maxcol is None:
 			if widths:
@@ -86,6 +84,7 @@
 		self.cs = cs
 		self.cursor = cursor
 		self.text = text
+        self.unitext = unitext
 		self.maxcol = maxcol
 
 	def rows(self):
@@ -274,6 +273,7 @@
 def CanvasCombine(l):
 	"""Stack canvases in l vertically and return resulting canvas."""
 	t = []
+        tu = []
 	a = []
 	c = []
 	rows = 0
@@ -281,6 +281,7 @@
 	cursor = None
 	for r in l:
 		t += r.text
+                tu += r.unitext
 		a += r.attr
 		c += r.cs
 		cols = max(cols, r.cols())
@@ -288,7 +289,7 @@
 			x,y = r.cursor
 			cursor = x, y+rows
 		rows = len( t )
-	d = Canvas(t, a, c, cursor, cols )
+	d = Canvas(t, a, c, cursor, cols, unitext=tu)
 	return d
 
 
@@ -305,12 +306,14 @@
 	l2 = [( l[i], l[i+1] ) for i in range(0,len(l),2)]
 	
 	t = []
+        tu = []
 	a = []
 	c = []
 	
 	rows = max([cnv.rows() for coff, cnv in l2])
 	for r in range(rows):
 		t.append([])
+                tu.append([])
 		a.append([])
 		c.append([])
 	
@@ -325,35 +328,41 @@
 		if x > xw:
 			pad = x-xw
 			tpad = " "*pad
+			tupad = u" "*pad
 			for r in range(rows):
 				t[r].append(tpad)
+				tu[r].append(tupad)
 				rle_append_modify(a[r],(None,pad))
 				rle_append_modify(c[r],(None,pad))
 		xw = x + cnv.cols()
 		i = 0
 		while i < cnv.rows():
 			t[i].append(cnv.text[i])
+			tu[i].append(unicode(cnv.text[i])) # FIXME: This line may crash!
 			rle_join_modify( a[i], cnv.attr[i] )
 			rle_join_modify( c[i], cnv.cs[i] )
 			i += 1
 		if i < rows:
 			pad = cnv.cols()
 			tpad = " "*pad
+			tupad = u" "*pad
 			while i < rows:
 				t[i].append(tpad)
+				tu[r].append(tupad)
 				rle_append_modify(a[i],(None,pad))
 				rle_append_modify(c[i],(None,pad))
 				i += 1 
 		if cnv.cursor:
 			cnv.translate_coords(x, 0)
 			cursor = cnv.cursor
-	d = Canvas( ["".join(lt) for lt in t], a, c, cursor, xw )
+	d = Canvas( ["".join(lt) for lt in t], a, c, cursor, xw , [u"".join(lt) for lt in tu])
 	return d
 
 
 def apply_text_layout( text, attr, ls, maxcol ):
 	utext = type(text)==type(u"")
 	t = []
+        ut = []
 	a = []
 	c = []
 	
@@ -394,6 +403,7 @@
 		line_layout = trim_line( line_layout, text, 0, maxcol )
 		
 		line = []
+                uline = []
 		linea = []
 		linec = []
 			
@@ -432,27 +442,32 @@
 				tseg, cs = apply_target_encoding(
 					text[s.offs:s.end])
 				line.append(tseg)
+                                uline.append(text[s.offs:s.end])
 				attrrange(s.offs, s.end, rle_len(cs))
 				rle_join_modify( linec, cs )
 			elif s.text:
 				tseg, cs = apply_target_encoding( s.text )
 				line.append(tseg)
+                                uline.append(s.text)
 				attrrange( s.offs, s.offs, len(tseg) )
 				rle_join_modify( linec, cs )
 			elif s.offs:
 				if s.sc:
 					line.append(" "*s.sc)
+                                        uline.append(u" "*s.sc)
 					attrrange( s.offs, s.offs, s.sc )
 			else:
 				line.append(" "*s.sc)
+				uline.append(u" "*s.sc)
 				linea.append((None, s.sc))
 				linec.append((None, s.sc))
 			
 		t.append("".join(line))
+		ut.append("".join(uline))
 		a.append(linea)
 		c.append(linec)
 		
-	return Canvas(t,a,c, maxcol=maxcol)
+	return Canvas(t,a,c, maxcol=maxcol,unitext=ut)
 
 
 
diff -urb urwid-0.9.7.1/urwid/listbox.py urwid-unicode/urwid/listbox.py
--- urwid-0.9.7.1/urwid/listbox.py	2006-10-09 17:18:35.000000000 +0200
+++ urwid-unicode/urwid/listbox.py	2006-12-31 01:10:27.000000000 +0100
@@ -282,7 +282,7 @@
 			bottom_pos = focus_pos
 			if fill_below: bottom_pos = fill_below[-1][1]
 			assert trim_bottom==0 and self.body.get_next(bottom_pos) == (None,None), "Listbox contents too short!  Probably urwid's fault (please report): %s" % `top,middle,bottom`
-			l.append( Canvas( [""] * (maxrow-rows), maxcol=maxcol ))
+			l.append( Canvas( [""] * (maxrow-rows), maxcol=maxcol, unitext=[u""] * (maxrow-rows) ))
 
 		return CanvasCombine( l )
 

Attachment: canvas.py
Description: application/python

_______________________________________________
Urwid mailing list
[email protected]
http://lists.excess.org/mailman/listinfo/urwid

Reply via email to