Subject: Re: [PATCH (GIT-GUI,GITK) 6/8] gitk: Port new encoding logic from git-gui.

From: Alexander Gavrilov <[email-masked]>
Date: Mon, 22 Sep 2008 13:02:52 +0400

On Monday 22 September 2008 12:20:28 Johannes Sixt wrote:
> Alexander Gavrilov schrieb:
> > On Monday 22 September 2008 11:25:43 Johannes Sixt wrote:
> >> Alexander Gavrilov schrieb:
> >>> Subject: [PATCH] gitk: Implement batch lookup and caching of encoding attrs.
> >>>
> >>> When the diff contains thousands of files, calling git-check-attr
> >>> once per file is very slow. With this patch gitk does attribute
> >>> lookup in batches of 30 files while reading the diff file list,
> >>> which leads to a very noticeable speedup.
> >> This one does not work for me: The correct is not picked up anymore,
> >> neither in Patch mode nor Tree mode. (It works as expected without this
> >> patch.)
> >>
> > 
> > OOPS, I forgot to copy the line that removes leading whitespace:
> 
> Thanks, with this it works now. The delay for a 1000 file patch is
> bearable (on Windows, but y'know, Windows types are masochists :-).

You can also try applying this patch (originally made for git-gui). It may save
additional 0.3 sec, especially for obscure legacy encodings.

P.S. I do believe there is a place for a library shared between gitk & git-gui.
This code duplication is ugly and annoying; moreover, they have different
indentation conventions, which get messed up...

--- >8 --- 
From: Alexander Gavrilov <[email-masked]>
Subject: [PATCH] git-gui: Optimize encoding name resolution using a lookup table.

Encoding menu construction does almost a hundred of encoding
resolutions, which with the old implementation led to a
small but noticeable delay.

Signed-off-by: Alexander Gavrilov <[email-masked]>
---
 gitk |   84 ++++++++++++++++++++++++++++++++++++++++++-----------------------
 1 files changed, 54 insertions(+), 30 deletions(-)

diff --git a/gitk b/gitk
index 254faa1..1355aa2 100755
--- a/gitk
+++ b/gitk
@@ -9779,39 +9779,63 @@ set encoding_aliases {
     { Big5 csBig5 }
 }
 
-proc tcl_encoding {enc} {
-    global encoding_aliases
-    set names [encoding names]
-    set lcnames [string tolower $names]
-    set enc [string tolower $enc]
-    set i [lsearch -exact $lcnames $enc]
-    if {$i < 0} {
-	# look for "isonnn" instead of "iso-nnn" or "iso_nnn"
-	if {[regsub {^(iso|cp|ibm|jis)[-_]} $enc {\1} encx]} {
-	    set i [lsearch -exact $lcnames $encx]
+proc build_encoding_table {} {
+	global encoding_aliases encoding_lookup_table
+
+	# Prepare the lookup list; cannot use lsort -nocase because
+	# of compatibility issues with older Tcl (e.g. in msysgit)
+	set names [list]
+	foreach item [encoding names] {
+		lappend names [list [string tolower $item] $item]
+	}
+	set names [lsort -ascii -index 0 $names]
+	# neither can we use lsearch -index
+	set lnames [list]
+	foreach item $names {
+		lappend lnames [lindex $item 0]
+	}
+
+	foreach grp $encoding_aliases {
+		set target {}
+		foreach item $grp {
+			set i [lsearch -sorted -ascii $lnames \
+					[string tolower $item]]
+			if {$i >= 0} {
+				set target [lindex $names $i 1]
+				break
+			}
+		}
+		if {$target eq {}} continue
+		foreach item $grp {
+			set encoding_lookup_table([string tolower $item]) $target
+		}
 	}
-    }
-    if {$i < 0} {
-	foreach l $encoding_aliases {
-	    set ll [string tolower $l]
-	    if {[lsearch -exact $ll $enc] < 0} continue
-	    # look through the aliases for one that tcl knows about
-	    foreach e $ll {
-		set i [lsearch -exact $lcnames $e]
-		if {$i < 0} {
-		    if {[regsub {^(iso|cp|ibm|jis)[-_]} $e {\1} ex]} {
-			set i [lsearch -exact $lcnames $ex]
-		    }
+
+	foreach item $names {
+		set encoding_lookup_table([lindex $item 0]) [lindex $item 1]
+	}
+}
+
+proc tcl_encoding {enc} {
+	global encoding_lookup_table
+	if {$enc eq {}} {
+		return {}
+	}
+	if {![info exists encoding_lookup_table]} {
+		build_encoding_table
+	}
+	set enc [string tolower $enc]
+	if {![info exists encoding_lookup_table($enc)]} {
+		# look for "isonnn" instead of "iso-nnn" or "iso_nnn"
+		if {[regsub {^(iso|cp|ibm|jis)[-_]} $enc {\1} encx]} {
+			set enc $encx
 		}
-		if {$i >= 0} break
-	    }
-	    break
 	}
-    }
-    if {$i >= 0} {
-	return [lindex $names $i]
-    }
-    return {}
+	if {[info exists encoding_lookup_table($enc)]} {
+		return $encoding_lookup_table($enc)
+	} else {
+		return {}
+	}
 }
 
 proc gitattr {path attr default} {
-- 
1.6.0.20.g6148bc