WWW class image import timing test

Hey has anyone else done a time test on importing external images directly into Unity via the WWW class?

I did a simple test on JPG’s and PNG’s of different dimensions (all are 72dpi) and they all take the same amount of time to load regardless of the size. Of course the server connection will produce varying results but they average about 0.3 seconds - even if the image is only 75x50 (around 7k). Here are the sizes and my results:

1200x800_1_4M.png = .28 sec
600x400_542k.png = .35
300x200_134k.png = .35
150x100_46k.png = .35
75x50_12k.png = .35
1200x800_255k.jpg =.35
600x400_114k.jpg =.35
300x200_42k.jpg =.35
150x100_16k.jpg = .35
75x50_7k.jpg = .35

Here’s the simple code I used…

var url = "[put any URL that points to images here]";
var startTime: float;
var endTime: float;

private var imageNames: Array = new Array("1200x800_1_4M.png","600x400_542k.png","300x200_134k.png","150x100_46k.png","75x50_12k.png","1200x800_255k.jpg","600x400_114k.jpg","300x200_42k.jpg","150x100_16k.jpg","75x50_7k.jpg");

function Start () {
     // Start a download of the given URL
    for (var i: int = 0;i<imageNames.length;i++) {
	    startTime = Time.time;
	    var www : WWW = new WWW (url+imageNames[i]);
	    
	    // Wait for download to complete
	    yield www;
	    
	    // assign texture
	    endTime = Time.time;
	    Debug.Log("Total download time for image "+imageNames[i]+" = "+(endTime-startTime));
    }
   
}

Seems strange that there is no difference in time even when images are are 7k versus 1.4M

Any thoughts?

Not sure why but I ran the test again the next day (after tweaking the code) and this is what came back. This is what I expected to see - the time getting shorter in relation to image size.

0.19 sec for a 7k image still seems a bit slow though. When I do this in a web browser it’s nearly instantaneous. The only thing I can think is there’s some kind of algorithm (maybe compression/decompression/conversion) going on in the background that is slowing the process down.

So, most of you using WWW class I am sure want to load external textures of at least 256x256 or 512x512 you’re looking at 0.5 to 1.0 seconds per texture. Seems like there’s got to be a faster method (via the web player).

Total download time for image 1200x800_1_4M.png = 1.792953
Total download time for image 600x400_542k.png = 1.267927
Total download time for image 300x200_134k.png = 0.620065
Total download time for image 150x100_46k.png = 0.4119582
Total download time for image 75x50_12k.png = 0.2400031
Total download time for image 1200x800_255k.jpg = 0.6119628
Total download time for image 600x400_114k.jpg = 0.8251672
Total download time for image 300x200_42k.jpg = 0.4599423
Total download time for image 150x100_16k.jpg = 0.2600436
Total download time for image 75x50_7k.jpg = 0.1919732

private var url = "[ URL goes here]";
var startTime: float;
var endTime: float;
var imgAvatar: GameObject;
private var imageNames: Array = new Array("1200x800_1_4M.png","600x400_542k.png","300x200_134k.png","150x100_46k.png","75x50_12k.png","1200x800_255k.jpg","600x400_114k.jpg","300x200_42k.jpg","150x100_16k.jpg","75x50_7k.jpg");

function Start () {
	
     // Start a download of the given URL
    for (var i: int = 0;i<imageNames.length;i++) {
    	Debug.Log("sending URL: "+url+imageNames[i]);
	    startTime = Time.time;
	    var www : WWW = new WWW (url+imageNames[i]);
	    
	    // Wait for download to complete
	    yield www;

	     // Print the error to the console
	    endTime = Time.time;
	    if ([url]www.error[/url] != null)
	    {
	        Debug.Log([url]www.error[/url]);    
	    }
	    Debug.Log("Total download time for image "+imageNames[i]+" = "+(endTime-startTime));
	    imgAvatar.renderer.material.mainTexture = [url]www.texture;[/url]
    }
   
}

It could have something to do with the way the yield www; statement works. Our non-multithreading Unity is probably checking in at fixed intervals to see if www.isDone. So it’s possible that the image loads in under 191ms but Unity just hasn’t discovered that it’s complete.

What you see there is the impact of Texture2D.LoadImage loading the bytes to fill the www.texture field for you to use. That just takes time (decompress the image to generate appropriate byte data, generate mipmaps).

What you see there is basically the base amount of time thats required to do this step.

The webplayer likely is faster cause the quality settings there commonly differ.
Also don’t check such timings in the editor just to be sure, the overhead of the console etc stacks up far and fast.

if you want to cut down the time, store the images in asset bundles. Also by now it might be possible that you can load DDS, not sure there, but they would load faster or should at least cause they are much smaller, don’t need decompression and can transport mipmaps

Wait a minute… are you telling me that WWW automatically generates a Texture2D before you use LoadImageIntoTexture or www.texture? Good god that’s annoying. I wrote a custom image class in order to work with pixel-data and avoid the overhead of the Texture2D class (mip-mapping, filtering, VRAM usage, etc.)… Are you telling me that WWW is making a Texture2D anyways? Even if I don’t call www.texture?

Hopefully changing the file-extension to something else would prevent this nonsense. I would also hope that WWW is not trying to ASCII encode every file it loads to populate the www.text property before you even try to access it.

From the docs:

“Each invocation of texture property allocates a new Texture2D.”

Hopefully this indicates the the “get” method of www.texture is generating the texture on demand.