Search Unity

WWW class image import timing test

Discussion in 'Editor & General Support' started by DeLong, Aug 26, 2010.

  1. DeLong

    DeLong

    Joined:
    Feb 22, 2009
    Posts:
    37
    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...

    Code (csharp):
    1.  
    2.  
    3. var url = "[put any URL that points to images here]";
    4. var startTime: float;
    5. var endTime: float;
    6.  
    7. 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");
    8.  
    9. function Start () {
    10.      // Start a download of the given URL
    11.     for (var i: int = 0;i<imageNames.length;i++) {
    12.         startTime = Time.time;
    13.         var www : WWW = new WWW (url+imageNames[i]);
    14.        
    15.         // Wait for download to complete
    16.         yield www;
    17.        
    18.         // assign texture
    19.         endTime = Time.time;
    20.         Debug.Log("Total download time for image "+imageNames[i]+" = "+(endTime-startTime));
    21.     }
    22.    
    23. }
    24.  
    25.  
    Seems strange that there is no difference in time even when images are are 7k versus 1.4M

    Any thoughts?
     
  2. DeLong

    DeLong

    Joined:
    Feb 22, 2009
    Posts:
    37
    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

    Code (csharp):
    1.  
    2. private var url = "[ URL goes here]";
    3. var startTime: float;
    4. var endTime: float;
    5. var imgAvatar: GameObject;
    6. 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");
    7.  
    8. function Start () {
    9.    
    10.      // Start a download of the given URL
    11.     for (var i: int = 0;i<imageNames.length;i++) {
    12.         Debug.Log("sending URL: "+url+imageNames[i]);
    13.         startTime = Time.time;
    14.         var www : WWW = new WWW (url+imageNames[i]);
    15.        
    16.         // Wait for download to complete
    17.         yield www;
    18.  
    19.          // Print the error to the console
    20.         endTime = Time.time;
    21.         if ([url]www.error[/url] != null)
    22.         {
    23.             Debug.Log([url]www.error[/url]);    
    24.         }
    25.         Debug.Log("Total download time for image "+imageNames[i]+" = "+(endTime-startTime));
    26.         imgAvatar.renderer.material.mainTexture = [url]www.texture;[/url]
    27.     }
    28.    
    29. }
    30.  
     
  3. Antitheory

    Antitheory

    Joined:
    Nov 14, 2010
    Posts:
    549
    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.
     
  4. Dreamora

    Dreamora

    Joined:
    Apr 5, 2008
    Posts:
    26,601
    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
     
  5. Antitheory

    Antitheory

    Joined:
    Nov 14, 2010
    Posts:
    549
    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.
     
  6. Antitheory

    Antitheory

    Joined:
    Nov 14, 2010
    Posts:
    549
    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.