summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--perl.h8
-rw-r--r--sv.c4
2 files changed, 12 insertions, 0 deletions
diff --git a/perl.h b/perl.h
index 59df0aaba7..74fb62ecb7 100644
--- a/perl.h
+++ b/perl.h
@@ -979,6 +979,14 @@ EXTERN_C int usleep(unsigned int);
#define PERL_STRLEN_ROUNDUP_QUANTUM Size_t_size
#endif
+/* sv_grow() will expand strings by at least a certain percentage of
+ the previously *used* length to avoid excessive calls to realloc().
+ The default is 25% of the current length.
+*/
+#ifndef PERL_STRLEN_EXPAND_SHIFT
+# define PERL_STRLEN_EXPAND_SHIFT 2
+#endif
+
#if defined(STANDARD_C) && defined(I_STDDEF)
# include <stddef.h>
# define STRUCT_OFFSET(s,m) offsetof(s,m)
diff --git a/sv.c b/sv.c
index a2f9867214..1f66e5b393 100644
--- a/sv.c
+++ b/sv.c
@@ -1536,6 +1536,10 @@ Perl_sv_grow(pTHX_ register SV *const sv, register STRLEN newlen)
s = SvPVX_mutable(sv);
if (newlen > SvLEN(sv)) { /* need more room? */
+ STRLEN minlen = SvCUR(sv);
+ minlen += (minlen >> PERL_STRLEN_EXPAND_SHIFT) + 10;
+ if (newlen < minlen)
+ newlen = minlen;
#ifndef Perl_safesysmalloc_size
newlen = PERL_STRLEN_ROUNDUP(newlen);
#endif