From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Leo Newsgroups: gmane.emacs.bugs Subject: bug#7089: 23.2; slow ansi-color-apply Date: Thu, 28 Oct 2010 12:03:18 +0800 Message-ID: References: NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: dough.gmane.org 1288239745 21748 80.91.229.12 (28 Oct 2010 04:22:25 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Thu, 28 Oct 2010 04:22:25 +0000 (UTC) Cc: 7089@debbugs.gnu.org To: Stefan Monnier Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Thu Oct 28 06:22:24 2010 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1PBK0N-0007Si-N2 for geb-bug-gnu-emacs@m.gmane.org; Thu, 28 Oct 2010 06:22:24 +0200 Original-Received: from localhost ([127.0.0.1]:47178 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PBK0N-0007uW-15 for geb-bug-gnu-emacs@m.gmane.org; Thu, 28 Oct 2010 00:22:23 -0400 Original-Received: from [140.186.70.92] (port=57393 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1PBK0E-0007R9-CE for bug-gnu-emacs@gnu.org; Thu, 28 Oct 2010 00:22:18 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1PBJrL-0005PN-Sp for bug-gnu-emacs@gnu.org; Thu, 28 Oct 2010 00:13:11 -0400 Original-Received: from debbugs.gnu.org ([140.186.70.43]:43788) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1PBJrL-0005Or-QS for bug-gnu-emacs@gnu.org; Thu, 28 Oct 2010 00:13:03 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.69) (envelope-from ) id 1PBJel-0004Hd-0Q; Thu, 28 Oct 2010 00:00:03 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Leo Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-To: owner@debbugs.gnu.org Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 28 Oct 2010 04:00:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 7089 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 7089-submit@debbugs.gnu.org id=B7089.128823837016441 (code B ref 7089); Thu, 28 Oct 2010 04:00:02 +0000 Original-Received: (at 7089) by debbugs.gnu.org; 28 Oct 2010 03:59:30 +0000 Original-Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1PBJeD-0004H7-Ix for submit@debbugs.gnu.org; Wed, 27 Oct 2010 23:59:29 -0400 Original-Received: from ppsw-52.csi.cam.ac.uk ([131.111.8.152]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1PBJeA-0004H2-Hs for 7089@debbugs.gnu.org; Wed, 27 Oct 2010 23:59:27 -0400 X-Cam-AntiVirus: no malware found X-Cam-SpamDetails: not scanned X-Cam-ScannerInfo: http://www.cam.ac.uk/cs/email/scanner/ Original-Received: from [59.57.34.138] (port=29802 helo=Victoria.local) by ppsw-52.csi.cam.ac.uk (smtp.hermes.cam.ac.uk [131.111.8.159]:587) with esmtpsa (PLAIN:sl392) (TLSv1:DHE-RSA-AES128-SHA:128) id 1PBJi8-0002Ni-Es (Exim 4.72) (return-path ); Thu, 28 Oct 2010 05:03:34 +0100 In-Reply-To: (Stefan Monnier's message of "Wed, 27 Oct 2010 22:38:17 -0400") User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (Mac OS X 10.6.4) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list Resent-Date: Thu, 28 Oct 2010 00:00:03 -0400 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:41187 Archived-At: On 2010-10-28 10:38 +0800, Stefan Monnier wrote: >> The following version fixed some glitches in setting ansi-color-context. >> Also I have received an email from Alex that welcomes the improvement. >> Let me know if I should send a patch in. > > Yes, a patch would be nice. Also a ChangeLog explaining the change > (which should hopefully explain why the new code is faster) would > be welcome. > > > Stefan Attached to the end of this message. I basically rewrite ansi-color-apply using re-search-forward (as in ansi-color-apply-on-region) which seems to be an order more efficient than string-match. I have been using the new version in eshell and it is almost as efficient as ansi-color-apply-on-region. It is very painful to use the original ansi-color-apply. Do you know for sure string-match is slower (more CPU intensive) than re-search-forward? Thanks. Leo -------------------------------- >From 724a620dd2d5301c32ecf4fbe6ce539db0c9bc8d Mon Sep 17 00:00:00 2001 Date: Thu, 28 Oct 2010 11:48:13 +0800 Subject: [PATCH] Rewrite ansi-color-apply using re-search-forward to improve efficiency. `string-match' uses a lot of CPU. --- lisp/ChangeLog | 5 ++++ lisp/ansi-color.el | 66 ++++++++++++++++++++++++++------------------------- 2 files changed, 39 insertions(+), 32 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 146c6c9..7088f28 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,8 @@ +2010-10-28 Leo + + * ansi-color.el (ansi-color-apply): Rewrite using + re-search-forward for speed. + 2010-10-03 Chong Yidong * minibuffer.el (completion--some, completion--do-completion) diff --git a/lisp/ansi-color.el b/lisp/ansi-color.el index 00162c9..6ef55e1 100644 --- a/lisp/ansi-color.el +++ b/lisp/ansi-color.el @@ -314,43 +314,45 @@ This function can be added to `comint-preoutput-filter-functions'. You cannot insert the strings returned into buffers using font-lock. See `ansi-color-unfontify-region' for a way around this." (let ((face (car ansi-color-context)) - (start 0) end escape-sequence result - colorized-substring) + start end fragment escape-sequence) ;; If context was saved and is a string, prepend it. (if (cadr ansi-color-context) (setq string (concat (cadr ansi-color-context) string) ansi-color-context nil)) - ;; Find the next escape sequence. - (while (setq end (string-match ansi-color-regexp string start)) - (setq escape-sequence (match-string 1 string)) - ;; Colorize the old block from start to end using old face. - (when face - (put-text-property start end 'ansi-color t string) - (put-text-property start end 'face face string)) - (setq colorized-substring (substring string start end) - start (match-end 0)) - ;; Eliminate unrecognized ANSI sequences. - (while (string-match ansi-color-drop-regexp colorized-substring) - (setq colorized-substring - (replace-match "" nil nil colorized-substring))) - (push colorized-substring result) - ;; Create new face, by applying escape sequence parameters. - (setq face (ansi-color-apply-sequence escape-sequence face))) - ;; if the rest of the string should have a face, put it there - (when face - (put-text-property start (length string) 'ansi-color t string) - (put-text-property start (length string) 'face face string)) - ;; save context, add the remainder of the string to the result - (let (fragment) - (if (string-match "\033" string start) - (let ((pos (match-beginning 0))) - (setq fragment (substring string pos)) - (push (substring string start pos) result)) - (push (substring string start) result)) + (prog1 + (with-temp-buffer + (insert string) + (setq start (point-min-marker)) + (goto-char start) + (while (re-search-forward ansi-color-drop-regexp nil t) + (replace-match "")) + (goto-char start) + ;; Find the next escape sequence. + (while (re-search-forward ansi-color-regexp nil t) + (setq end (match-beginning 0)) + (when face + (put-text-property start end 'ansi-color t) + (put-text-property start end 'face face)) + (setq start (copy-marker (match-end 0))) + (setq escape-sequence (match-string 1)) + (replace-match "") + (setq face (ansi-color-apply-sequence escape-sequence face))) + ;; Search for the possible start of a new escape sequence + (if (re-search-forward "\033" nil t) + (setq fragment + (delete-and-extract-region (match-beginning 0) + (point-max)))) + ;; If the rest of the string should have a face, put it there + (when face + (put-text-property start (point-max) 'ansi-color t) + (put-text-property start (point-max) 'face face)) + ;; Return the string + (buffer-string)) + ;; Save context; NB: ansi-color-context is buffer-local so set it after + ;; exit the temp buffer. (if (or face fragment) - (setq ansi-color-context (list face fragment)) - (setq ansi-color-context nil))) - (apply 'concat (nreverse result)))) + (setq ansi-color-context (list face fragment)) + (setq ansi-color-context nil))))) ;; Working with regions -- 1.7.3