git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 4/4] utf8.c: speculatively assume utf-8 in strbuf_add_wrapped_text()

From
René Scharfe <rene.scharfe@lsrfire.ath.cx>
Date
Feb 19, 2010, 22:20 UTC
Message-ID
<4B7F0EBC.4060209@lsrfire.ath.cx>
In-Reply-To
<4B7F0D08.6040608@lsrfire.ath.cx>

is_utf8() works by calling utf8_width() for each character at the supplied location. In strbuf_add_wrapped_text(), we do that anyway while wrapping the lines. So instead of checking the encoding beforehand, optimistically assume that it's utf-8 and wrap along until an invalid character is hit, and when that happens start over.

This pays off if the text consists only of valid utf-8 characters. The following command was run against the Linux kernel repo with git 1.7.0:

	$ time git log --format='%b' v2.6.32 >/dev/null
	real	0m2.679s
	user	0m2.580s
	sys	0m0.100s
	$ time git log --format='%w(60,4,8)%b' >/dev/null
	real	0m4.342s
	user	0m4.230s
	sys	0m0.110s
And with this patch series:
	$ time git log --format='%w(60,4,8)%b' >/dev/null
	real	0m3.741s
	user	0m3.630s
	sys	0m0.110s
So the cost of wrapping is reduced to 70% in this case.
Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
---
Missing: numbers for a non-utf-8 repo.
 utf8.c |   23 +++++++++++++++++------
 1 files changed, 17 insertions(+), 6 deletions(-)
diff --git a/utf8.c b/utf8.c
index 87437b0..84cfc72 100644
--- a/utf8.c
+++ b/utf8.c
@@ -324,16 +324,21 @@ static size_t display_mode_esc_sequence_len(const char *s)
  * consumed (and no extra indent is necessary for the first line).
  */
 int strbuf_add_wrapped_text(struct strbuf *buf,
-		const char *text, int indent, int indent2, int width)
+		const char *text, int indent1, int indent2, int width)
 {
-	int w = indent, assume_utf8 = is_utf8(text);
-	const char *bol = text, *space = NULL;
+	int indent, w, assume_utf8 = 1;
+	const char *bol, *space, *start = text;
+	size_t orig_len = buf->len;
 
 	if (width <= 0) {
-		strbuf_add_indented_text(buf, text, indent, indent2);
+		strbuf_add_indented_text(buf, text, indent1, indent2);
 		return 1;
 	}
 
+retry:
+	bol = text;
+	w = indent = indent1;
+	space = NULL;
 	if (indent < 0) {
 		w = -indent;
 		space = text;
@@ -385,9 +390,15 @@ new_line:
 			}
 			continue;
 		}
-		if (assume_utf8)
+		if (assume_utf8) {
 			w += utf8_width(&text, NULL);
-		else {
+			if (!text) {
+				assume_utf8 = 0;
+				text = start;
+				strbuf_setlen(buf, orig_len);
+				goto retry;
+			}
+		} else {
 			w++;
 			text++;
 		}
-- 
1.7.0
Previous: René ScharfeNext: Johannes Schindelin
Message 5 of 8 in “utf8.c: strbuf'ify strbuf_add_wrapped_text()”
  1. 0/4 utf8.c: strbuf'ify strbuf_add_wrapped_text()René Scharfe, Feb 19, 2010
  2. 1/4 utf8.c: remove print_wrapped_text()René Scharfe, Feb 19, 2010
  3. 2/4 utf8.c: remove print_spaces()René Scharfe, Feb 19, 2010
  4. 3/4 utf8.c: remove strbuf_write()René Scharfe, Feb 19, 2010
  5. 4/4 utf8.c: speculatively assume utf-8 in strbuf_add_wrapped_text()René Scharfe, Feb 19, 2010
  6. Johannes SchindelinFeb 20, 2010
  7. Junio C HamanoFeb 20, 2010
  8. Johannes SchindelinFeb 20, 2010

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.