@@ -70,8 +70,6 @@ typedef __uint128_t wideint_t;
7070typedef uint64_t wideint_t ;
7171#endif
7272
73- size_t jl_arr_xtralloc_limit = 0 ;
74-
7573#define MAXINTVAL (((size_t)-1)>>1)
7674
7775static jl_array_t * _new_array_ (jl_value_t * atype , uint32_t ndims , size_t * dims ,
@@ -758,16 +756,23 @@ static void NOINLINE array_try_unshare(jl_array_t *a)
758756 }
759757}
760758
761- static size_t limit_overallocation ( jl_array_t * a , size_t alen , size_t newlen , size_t inc )
759+ size_t overallocation ( size_t maxsize )
762760{
763- // Limit overallocation to jl_arr_xtralloc_limit
764- size_t es = a -> elsize ;
765- size_t xtra_elems_mem = (newlen - a -> offset - alen - inc ) * es ;
766- if (xtra_elems_mem > jl_arr_xtralloc_limit ) {
767- // prune down
768- return alen + inc + a -> offset + (jl_arr_xtralloc_limit / es );
769- }
770- return newlen ;
761+ if (maxsize < 8 )
762+ return 8 ;
763+ // compute maxsize = maxsize + 4*maxsize^(7/8) + maxsize/8
764+ // for small n, we grow faster than O(n)
765+ // for large n, we grow at O(n/8)
766+ // and as we reach O(memory) for memory>>1MB,
767+ // this means we end by adding about 10% of memory each time
768+ int exp2 = sizeof (maxsize ) * 8 -
769+ #ifdef _P64
770+ __builtin_clzll (maxsize );
771+ #else
772+ __builtin_clz (maxsize );
773+ #endif
774+ maxsize += ((size_t )1 << (exp2 * 7 / 8 )) * 4 + maxsize / 8 ;
775+ return maxsize ;
771776}
772777
773778STATIC_INLINE void jl_array_grow_at_beg (jl_array_t * a , size_t idx , size_t inc ,
@@ -815,10 +820,12 @@ STATIC_INLINE void jl_array_grow_at_beg(jl_array_t *a, size_t idx, size_t inc,
815820 size_t nb1 = idx * elsz ;
816821 if (inc > (a -> maxsize - n ) / 2 - (a -> maxsize - n ) / 20 ) {
817822 // not enough room for requested growth from end of array
818- size_t newlen = a -> maxsize == 0 ? inc * 2 : a -> maxsize * 2 ;
823+ size_t newlen = inc * 2 ;
819824 while (n + 2 * inc > newlen - a -> offset )
820825 newlen *= 2 ;
821- newlen = limit_overallocation (a , n , newlen , 2 * inc );
826+ size_t newmaxsize = overallocation (a -> maxsize );
827+ if (newlen < newmaxsize )
828+ newlen = newmaxsize ;
822829 size_t newoffset = (newlen - newnrows ) / 2 ;
823830 if (!array_resize_buffer (a , newlen )) {
824831 data = (char * )a -> data + oldoffsnb ;
@@ -903,12 +910,11 @@ STATIC_INLINE void jl_array_grow_at_end(jl_array_t *a, size_t idx,
903910 if (__unlikely (reqmaxsize > a -> maxsize )) {
904911 size_t nb1 = idx * elsz ;
905912 size_t nbinc = inc * elsz ;
906- // if the requested size is more than 2x current maxsize, grow exactly
907- // otherwise double the maxsize
908- size_t newmaxsize = reqmaxsize >= a -> maxsize * 2
909- ? (reqmaxsize < 4 ? 4 : reqmaxsize )
910- : a -> maxsize * 2 ;
911- newmaxsize = limit_overallocation (a , n , newmaxsize , inc );
913+ // grow either by our computed overallocation factor or exactly the requested size,
914+ // whichever is larger
915+ size_t newmaxsize = overallocation (a -> maxsize );
916+ if (newmaxsize < reqmaxsize )
917+ newmaxsize = reqmaxsize ;
912918 size_t oldmaxsize = a -> maxsize ;
913919 int newbuf = array_resize_buffer (a , newmaxsize );
914920 char * newdata = (char * )a -> data + a -> offset * elsz ;
0 commit comments