Even if the number of points looks the same, you have 2 cases:
- render 1 shape with 100k points
- render 100k shapes but simple (4 edges)
For every draw/fill operation, Marlin rasterizes the shape in tiles (masks) and the java2d pipeline performs surface blending (C loops for geoserver), using Paint & Composite.
That's nice as every shape can have its own color and transparency : overlapping points are fading / mixing...
As you pointed, Marlin is fast with 100k polygons, I think the pixel blending stage is the bottleneck.
Using jvisualvm, it is quite easy to see if how much time is taken by MaskFill methods().
Yes, I think it is the case.
This is slower as every shape must be painted... so it represents 100k blending operations !
If you do not use transparency nor different colors, it would be possible to paint 1 shape made of many rectangles (closed shape), to have less blending passes.
That's the painter problem: colors are mixed using alpha compositors, transparency...
Probably it would be best to cache symbols into images and use drawImage in geoserver, but it may be less precise (re-gridding problem of AA mask).
Finally for such dense plots, there are certainly other approaches to make heatmaps or density plots...
Cheers,
Laurent