Jim, I answer here to your two mails:
" By "bucket 0 sizes", I meant the size of the array in the first resize bucket, not the literal number 0. My thoughts were that we would simply initialize the arrays to the smallest of the cached growable array sizes. This would eliminate even more cases where we need to resize, but at the expense of making the initial cost of the rasterizer larger. How much larger would that be - I didn't calculate. If you set them to the literal number 0, then we always immediately incur a resize overhead, no? " I thought you wanted to remove completely initial arrays to simplify the code and rely on the cache only: that's why I tested the impact of such solution and I set initial arrays to [0] to force the cache usage: get/put. > I still have no idea what you mean when you say "arrays = [0]". > > Does that mean "new foo[0]"? Or "new foo[getBucketSize of bucket #0]"? I tested "new foo[0]", sorry I misunderstood. > The latter is what I was envisioning using... So you propose to enlarge the memory footprint consumed by initial arrays. The bucket #0 size is for now 4096 (16K for int/float arrays) and 32768 (32K) for dirty bytes. It will sometimes larger or smaller depending on the use case: Here is a summary of initial arrays with their current capacities to minimize the memory footprint: INITIAL_ARRAY = 256: MarlinCache 75: final int[] touchedTile_initial = new int[INITIAL_ARRAY]; // 1 tile lineDasher 72: final float[] dashes_initial = new float[INITIAL_ARRAY]; 79: private final float[] firstSegmentsBuffer_initial = new float[INITIAL_ARRAY + 1]; 3 arrays [256 x 4 = 1K] = 3K in total. INITIAL_SMALL_ARRAY = 1024: Renderer 170: private final int[] crossings_initial = new int[INITIAL_SMALL_ARRAY]; // 4K 172: private final int[] edgePtrs_initial = new int[INITIAL_SMALL_ARRAY + 1]; // 4K 174: private final int[] aux_crossings_initial = new int[INITIAL_SMALL_ARRAY]; // 4K 176: private final int[] aux_edgePtrs_initial = new int[INITIAL_SMALL_ARRAY + 1]; // 4K 4 arrays [1024 x 4 = 4K] = 16K in total. INITIAL_AA_ARRAY = INITIAL_PIXEL_DIM = 2048 (tunable by system property): Renderer 690: private final int[] alphaLine_initial = new int[INITIAL_AA_ARRAY]; // 8K 1 array [2048 x 4 = 8K] = 8K in total. => 8 arrays (capacity < 4096) = 27K in total If all set to capacity = 4096 => 8 x 4 x 4 = 128K INITIAL_MEDIUM_ARRAY = 4096: MarlinRenderingEnginecreateStrokedShape 90: (rdrCtx.p2d = new Path2D.Float(Path2D.WIND_NON_ZERO, INITIAL_MEDIUM_ARRAY)) Lazy Path2D allocation with initialCapacity = 4096 including byte[4096] and float[2 * 4096] = 36K in total. INITIAL_LARGE_ARRAY = 8192: StrokerPolyStack 1203: private final float[] curves_initial = new float[INITIAL_LARGE_ARRAY + 1]; // 32K 1204: private final byte[] curveTypes_initial = new byte[INITIAL_LARGE_ARRAY + 1]; // 8K 2 arrays = 40K in total INITIAL_BUCKET_ARRAY = INITIAL_PIXEL_DIM * SUBPIXEL_POSITIONS_Y = 16384: Renderer 199: private final int[] edgeBuckets_initial = new int[INITIAL_BUCKET_ARRAY + 1]; // 64K private final int[] edgeBucketCounts_initial = new int[INITIAL_BUCKET_ARRAY + 1]; // 64K 2 arrays = 128K in total INITIAL_CHUNK_ARRAY = TILE_SIZE * INITIAL_PIXEL_DIM = 65536: MarlinCache 73: final byte[] rowAAChunk_initial = new byte[INITIAL_CHUNK_ARRAY + 1]; // 64K 1 array = 64K in total INITIAL_EDGES_CAPACITY = INITIAL_ARRAY_16K << 3 = 131072: Renderer 190: = new OffHeapEdgeArray(INITIAL_EDGES_CAPACITY); // 128K 1 large array for edge data = 128K Grand total = 27 + 40 + 128 + 64 + 128 = 387K + lazy path2d. To conclude, large initial arrays (polystack, edge buckets, aa chunks, edge data) are mainly depending on image / shape scale or complexity. I agree smaller arrays could be enlarged. Besides, initial sizes should stay consistent for byte/int/float arrays that are related: see Stroker.Polystack Laurent