@@ -70,8 +70,6 @@ typedef __uint128_t wideint_t;
70
70
typedef uint64_t wideint_t ;
71
71
#endif
72
72
73
- size_t jl_arr_xtralloc_limit = 0 ;
74
-
75
73
#define MAXINTVAL (((size_t)-1)>>1)
76
74
77
75
static 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)
758
756
}
759
757
}
760
758
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 )
762
760
{
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 ;
771
776
}
772
777
773
778
STATIC_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,
815
820
size_t nb1 = idx * elsz ;
816
821
if (inc > (a -> maxsize - n ) / 2 - (a -> maxsize - n ) / 20 ) {
817
822
// 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 ;
819
824
while (n + 2 * inc > newlen - a -> offset )
820
825
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 ;
822
829
size_t newoffset = (newlen - newnrows ) / 2 ;
823
830
if (!array_resize_buffer (a , newlen )) {
824
831
data = (char * )a -> data + oldoffsnb ;
@@ -903,12 +910,11 @@ STATIC_INLINE void jl_array_grow_at_end(jl_array_t *a, size_t idx,
903
910
if (__unlikely (reqmaxsize > a -> maxsize )) {
904
911
size_t nb1 = idx * elsz ;
905
912
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 ;
912
918
size_t oldmaxsize = a -> maxsize ;
913
919
int newbuf = array_resize_buffer (a , newmaxsize );
914
920
char * newdata = (char * )a -> data + a -> offset * elsz ;
0 commit comments