summaryrefslogtreecommitdiff
path: root/src/insdel.c
diff options
context:
space:
mode:
authorStefan Monnier <monnier@iro.umontreal.ca>2017-02-19 13:12:16 -0500
committerStefan Monnier <monnier@iro.umontreal.ca>2017-02-19 13:12:16 -0500
commit5c1ebfc504bc0649a9e1105b1d9265c461739254 (patch)
treeb6f7ec31424cf57f21a57beb2570e21d94387d83 /src/insdel.c
parentf03d936cd7a9e22f68c8ac1c14516d5079307b90 (diff)
downloademacs-5c1ebfc504bc0649a9e1105b1d9265c461739254.tar.gz
* src/insdel.c (make_gap): Increase enough to avoid O(N^2) behavior.
Diffstat (limited to 'src/insdel.c')
-rw-r--r--src/insdel.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/src/insdel.c b/src/insdel.c
index 3f933b0ad85..8b684fd2780 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -560,7 +560,20 @@ void
make_gap (ptrdiff_t nbytes_added)
{
if (nbytes_added >= 0)
- make_gap_larger (nbytes_added);
+ /* With set-buffer-multibyte on a large buffer, we can end up growing the
+ * buffer *many* times. Avoid an O(N^2) behavior by increasing by an
+ * amount at least proportional to the size of the buffer.
+ * On my test (a 223.9MB zip file on a Thinkpad T61):
+ * With /5 => 24s
+ * With /32 => 25s
+ * With /64 => 26s
+ * With /128 => 28s
+ * With /1024 => 51s
+ * With /4096 => 131s
+ * With /∞ => gave up after 858s
+ * Of couse, ideally we should never call set-buffer-multibyte on
+ * a non-empty buffer (e.g. use buffer-swa-text instead). */
+ make_gap_larger (max (nbytes_added, (Z - BEG) / 64));
#if defined USE_MMAP_FOR_BUFFERS || defined REL_ALLOC || defined DOUG_LEA_MALLOC
else
make_gap_smaller (-nbytes_added);