= Nested Network Image Compression Benchmarks = Currently !NN images are cached as Java !BufferedImage objects (in src/ding/view/DGraphView.java) with image width and height set to DEF_SNAPSHOT_SIZE which is 400. Asssuming a pixel size of 4 bytes, this would imply a size per cached image of 640kB. Even at this modest resolution this size can cause serious memory allocation problems when hundreds of nodes contain nested networks! One possible workaround is to cache the images as JPEGs or PNGs. Please note that using JPEGs does not necessarily imply lossy compression! Below are the results of a few experiments using this idea. (The compression factors have been determined by instrumenting the convertToCompressedImage() method in !DGraphView and assuming that the uncompressed image size is 640kB.) || '''File name''' || '''img type''' || '''min. img compr. ratio''' || '''max. img. compr. ratio''' || '''avg. img. compr. ratio''' || || 10LargeNetworks.nnf || PNG || 56.4 || 115.6 || 78.3 || || 300SmallNetworks.nnf || PNG || 14.9 || 53.8 || 27.5 || || 1000SmallNetworks.nnf || PNG || 11.1 || 40.3 || 19.0 || || 10LargeNetworks.nnf || JPEG || 4.7 || 7.4 || 5.6 || || 300SmallNetworks.nnf || JPEG || 9.9 || 28.2 || 17.4 || || 1000SmallNetworks.nnf || JPEG || 8.4 || 22.6 || 13.4 || || 10LargeNetworks.nnf || RLE || 1.8 || 2.2 || 2.0 || || 300SmallNetworks.nnf || RLE || 2.5 || 9.5 || 5.2 || || 1000SmallNetworks.nnf || RLE || 2.0 || 7.1 || 3.6 || This seems to indicate that we should probably generate PNG images rather than JPEGs. Below we are comparing rendering using BufferedImage caching, i.e. using the original strategy, vs. PNG caching. Please note that this is only the overall time spent creating TexturePaints and nothing else. In other words it is '''not''' the overall time for rendering! || '''File name''' || '''method''' || '''cumulative time in ms''' || || 10LargeNetworks.nnf || PNG caching || 1349 || || 300SmallNetworks.nnf || PNG caching || 2982 || || 1000SmallNetworks.nnf || PNG caching || 3064 || || 10LargeNetworks.nnf || !BufferedImage caching || 327 || || 300SmallNetworks.nnf || !BufferedImage caching || 262 || || 1000SmallNetworks.nnf || !BufferedImage caching || 278 || || 10LargeNetworks.nnf || RLE caching || 254 || || 300SmallNetworks.nnf || RLE caching || 444 || || 1000SmallNetworks.nnf || RLE caching || 1122 || This shows that in the worst case, the PNG caching strategy adds just under 3s to the overall rendering time. While this seems a lot, it has to be weighed against the much smaller overall memory footprint which for large numbers of nested networks can easily be an order of magnitude lower than when caching BufferedImage objects. Note: A further speedup is conceivable: We could try to run-length encode (RLE) raw BufferedImage data. This would probably be very fast and add much lower overhead than PNG images but would require testing across platforms since we have no idea what the internal data representation of a BufferedImage is. It is likely though to consist of 4-byte pixels which makes RLE compression based on Java int arrays a tempting strategy.