aboutsummaryrefslogtreecommitdiffstats
path: root/src/editfns.c
diff options
context:
space:
mode:
authorPaul Eggert2017-10-04 14:29:58 -0700
committerPaul Eggert2017-10-04 14:45:08 -0700
commit3db388b0bf83d3138562f09ce25fab8ba89bcc81 (patch)
treeff86fa2e529cdd9187a12e88d193b4416d60c26e /src/editfns.c
parent4e0b67ed27114fa2cbebca32567089fd8fa78425 (diff)
downloademacs-3db388b0bf83d3138562f09ce25fab8ba89bcc81.tar.gz
emacs-3db388b0bf83d3138562f09ce25fab8ba89bcc81.zip
Speed up (format "%s" STRING) and the like
Although the Lisp manual said that ‘format’ returns a newly-allocated string, this was not true for a few cases like (format "%s" ""), and fixing the documentation to allow reuse of arguments lets us improve performance in common cases like (format "foo") and (format "%s" "foo") (Bug#28625). * doc/lispref/strings.texi (Formatting Strings): * etc/NEWS: Say that the result of ‘format’ might not be newly allocated. * src/callint.c (Fcall_interactively): * src/dbusbind.c (XD_OBJECT_TO_STRING): * src/editfns.c (Fmessage, Fmessage_box): * src/xdisp.c (vadd_to_log, Ftrace_to_stderr): Just use Fformat or Fformat_message, as that’s simpler and no longer makes unnecessary copies. * src/editfns.c (styled_format): Remove last argument, as it is no longer needed: all callers now want it to behave as if it were true. All remaining callers changed. Make this function static again. Simplify the function now that we no longer need to worry about whether the optimization is allowed.
Diffstat (limited to 'src/editfns.c')
-rw-r--r--src/editfns.c28
1 files changed, 11 insertions, 17 deletions
diff --git a/src/editfns.c b/src/editfns.c
index e326604467c..d88a913c667 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -74,6 +74,7 @@ static Lisp_Object format_time_string (char const *, ptrdiff_t, struct timespec,
74static long int tm_gmtoff (struct tm *); 74static long int tm_gmtoff (struct tm *);
75static int tm_diff (struct tm *, struct tm *); 75static int tm_diff (struct tm *, struct tm *);
76static void update_buffer_properties (ptrdiff_t, ptrdiff_t); 76static void update_buffer_properties (ptrdiff_t, ptrdiff_t);
77static Lisp_Object styled_format (ptrdiff_t, Lisp_Object *, bool);
77 78
78#ifndef HAVE_TM_GMTOFF 79#ifndef HAVE_TM_GMTOFF
79# define HAVE_TM_GMTOFF false 80# define HAVE_TM_GMTOFF false
@@ -3958,7 +3959,7 @@ usage: (message FORMAT-STRING &rest ARGS) */)
3958 } 3959 }
3959 else 3960 else
3960 { 3961 {
3961 Lisp_Object val = styled_format (nargs, args, true, false); 3962 Lisp_Object val = Fformat_message (nargs, args);
3962 message3 (val); 3963 message3 (val);
3963 return val; 3964 return val;
3964 } 3965 }
@@ -3984,7 +3985,7 @@ usage: (message-box FORMAT-STRING &rest ARGS) */)
3984 } 3985 }
3985 else 3986 else
3986 { 3987 {
3987 Lisp_Object val = styled_format (nargs, args, true, false); 3988 Lisp_Object val = Fformat_message (nargs, args);
3988 Lisp_Object pane, menu; 3989 Lisp_Object pane, menu;
3989 3990
3990 pane = list1 (Fcons (build_string ("OK"), Qt)); 3991 pane = list1 (Fcons (build_string ("OK"), Qt));
@@ -4140,7 +4141,7 @@ produced text.
4140usage: (format STRING &rest OBJECTS) */) 4141usage: (format STRING &rest OBJECTS) */)
4141 (ptrdiff_t nargs, Lisp_Object *args) 4142 (ptrdiff_t nargs, Lisp_Object *args)
4142{ 4143{
4143 return styled_format (nargs, args, false, true); 4144 return styled_format (nargs, args, false);
4144} 4145}
4145 4146
4146DEFUN ("format-message", Fformat_message, Sformat_message, 1, MANY, 0, 4147DEFUN ("format-message", Fformat_message, Sformat_message, 1, MANY, 0,
@@ -4156,16 +4157,13 @@ and right quote replacement characters are specified by
4156usage: (format-message STRING &rest OBJECTS) */) 4157usage: (format-message STRING &rest OBJECTS) */)
4157 (ptrdiff_t nargs, Lisp_Object *args) 4158 (ptrdiff_t nargs, Lisp_Object *args)
4158{ 4159{
4159 return styled_format (nargs, args, true, true); 4160 return styled_format (nargs, args, true);
4160} 4161}
4161 4162
4162/* Implement ‘format-message’ if MESSAGE is true, ‘format’ otherwise. 4163/* Implement ‘format-message’ if MESSAGE is true, ‘format’ otherwise. */
4163 If NEW_RESULT, the result is a new string; otherwise, the result
4164 may be one of the arguments. */
4165 4164
4166Lisp_Object 4165static Lisp_Object
4167styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message, 4166styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
4168 bool new_result)
4169{ 4167{
4170 ptrdiff_t n; /* The number of the next arg to substitute. */ 4168 ptrdiff_t n; /* The number of the next arg to substitute. */
4171 char initial_buffer[4000]; 4169 char initial_buffer[4000];
@@ -4195,9 +4193,6 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message,
4195 /* The start and end bytepos in the output string. */ 4193 /* The start and end bytepos in the output string. */
4196 ptrdiff_t start, end; 4194 ptrdiff_t start, end;
4197 4195
4198 /* Whether the argument is a newly created string. */
4199 bool_bf new_string : 1;
4200
4201 /* Whether the argument is a string with intervals. */ 4196 /* Whether the argument is a string with intervals. */
4202 bool_bf intervals : 1; 4197 bool_bf intervals : 1;
4203 } *info; 4198 } *info;
@@ -4241,6 +4236,9 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message,
4241 ptrdiff_t ispec; 4236 ptrdiff_t ispec;
4242 ptrdiff_t nspec = 0; 4237 ptrdiff_t nspec = 0;
4243 4238
4239 /* True if a string needs to be allocated to hold the result. */
4240 bool new_result = false;
4241
4244 /* If we start out planning a unibyte result, 4242 /* If we start out planning a unibyte result,
4245 then discover it has to be multibyte, we jump back to retry. */ 4243 then discover it has to be multibyte, we jump back to retry. */
4246 retry: 4244 retry:
@@ -4360,7 +4358,6 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message,
4360 if (nspec < ispec) 4358 if (nspec < ispec)
4361 { 4359 {
4362 spec->argument = args[n]; 4360 spec->argument = args[n];
4363 spec->new_string = false;
4364 spec->intervals = false; 4361 spec->intervals = false;
4365 nspec = ispec; 4362 nspec = ispec;
4366 } 4363 }
@@ -4378,7 +4375,6 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message,
4378 { 4375 {
4379 Lisp_Object noescape = conversion == 'S' ? Qnil : Qt; 4376 Lisp_Object noescape = conversion == 'S' ? Qnil : Qt;
4380 spec->argument = arg = Fprin1_to_string (arg, noescape); 4377 spec->argument = arg = Fprin1_to_string (arg, noescape);
4381 spec->new_string = true;
4382 if (STRING_MULTIBYTE (arg) && ! multibyte) 4378 if (STRING_MULTIBYTE (arg) && ! multibyte)
4383 { 4379 {
4384 multibyte = true; 4380 multibyte = true;
@@ -4397,7 +4393,6 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message,
4397 goto retry; 4393 goto retry;
4398 } 4394 }
4399 spec->argument = arg = Fchar_to_string (arg); 4395 spec->argument = arg = Fchar_to_string (arg);
4400 spec->new_string = true;
4401 } 4396 }
4402 4397
4403 if (!EQ (arg, args[n])) 4398 if (!EQ (arg, args[n]))
@@ -4421,7 +4416,6 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message,
4421 if (conversion == 's') 4416 if (conversion == 's')
4422 { 4417 {
4423 if (format == end && format - format_start == 2 4418 if (format == end && format - format_start == 2
4424 && (!new_result || spec->new_string)
4425 && ! string_intervals (args[0])) 4419 && ! string_intervals (args[0]))
4426 return arg; 4420 return arg;
4427 4421