Search Unity

  1. Unity 2017.2 beta is now available for download.
    Dismiss Notice
  2. Unity 2017.1 is now released.
    Dismiss Notice
  3. Introducing the Unity Essentials Packs! Find out more.
    Dismiss Notice
  4. Check out all the fixes for 5.6 on the patch releases page.
    Dismiss Notice
  5. Help us improve the editor usability and artist workflows. Join our discussion to provide your feedback.
    Dismiss Notice

Is saving/loading to PlayerPrefs still slow for large quantities of data?

Discussion in 'iOS and tvOS' started by Ben-BearFish, Aug 11, 2012.

  1. Ben-BearFish

    Ben-BearFish

    Joined:
    Sep 6, 2011
    Posts:
    1,090
    I read on these forums that if you were saving large quantities of data, e.g. 300 to 500 variables, that the time it takes to save to PlayerPrefs is incredibly slow, and that you should save the data yourself.

    There have been suggestions such as using PreviewLabs own Playerprefs, which uses its own hashtables:

    http://www.previewlabs.com/writing-playerprefs-fast/

    Or writing my own serializer. The main reason I'm hesitant to use these though, is that there is room for error on my part, when I for sure know PlayerPrefs will for sure work. Normally human error on a save wouldn't be that big of a deal, except for the fact my App has In-App Purchases and if the data is incorrectly saved somehow this causes major issues for me and the player.

    My question to the forums and Unity users, especially iOS developers, is this still the case with PlayerPrefs? Because I noticed much of these posts were posted early last year 2011, and since then Unity has seen major Updates with Unity 3.4 and Unity 3.5, so I was wondering if the speed of PlayerPref saving and loading has been optimized/improved at all, or is it still the same slow speed when saving large quantities of data?
     
  2. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    19,661
  3. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,070
    I try and save at "dead moments" in the game. My game works on loops of player movement. At the end of a loop, I may have set several bits of data. Vs saving each time, I save once at end of loop.
     
  4. Ben-BearFish

    Ben-BearFish

    Joined:
    Sep 6, 2011
    Posts:
    1,090
    I see, so regarding the posts,especially the ones done by PreviewLabs, they make PlayerPrefs seem so slow in comparison to theirs. Is there a reason they do that, because I feel like it gives mixed signals about the power of PlayerPrefs. Thank you for both your answers.
     
  5. prime31

    prime31

    Joined:
    Oct 9, 2008
    Posts:
    6,427
    That class is a horrendous way to save data. It allocates tons and tons of strings instead of using a StringBuilder and casts every Hashtable value. PlayerPrefs uses NSUserDefaults which is plenty fast. If you have huge amounts of data it is of course best to store it outside of PlayerPrefs in chunks of like data if performance is your main goal.
     
  6. bernardfrancois

    bernardfrancois

    Joined:
    Oct 29, 2009
    Posts:
    370
    We've written our PlayerPrefs class more than a year ago - at a time when it was very slow to set a large amount of key/value pairs, especially on Android.

    The main optimization for us was that it's doing everything in the device's memory - as the kind of performance we got from the native class at the time was making believe that every time a PlayerPrefs variabe is changed, it would write to the device's disk / flash memory. As doing this fixed the performance issue for us, we didn't further optimize it.
    In our concrete case, we had to wait more than 60s to save several hundreds of key/value pairs, while this dropped below 0.5s after writing our own class. We didn't care about having an other 50% performance gain (for instance) beyond that point.

    Since I thought other people could have had similar performance issues with the built-in class, I made the class public domain. Everyone is free to modify and redistribute the class, or if you've an improved version of it I'll be happy to use it to replace the origin alversion.

    Perhaps if I can find some time, I'll re-test it with the current Unity version to have a clear idea if the class still makes sense to use and mention our findings in the original blog article here.

    For the time being, I suggest that people who do notice a performance issue on iOS or Android while setting a large amount of PlayerPrefs key/value pairs give it a try and see if it can be a quick fix for them.

    [edit]
    Please also note that PlayerPrefs.Save didn't exist yet at the time we wrote our class (we called it Flush in our class). It sounds likely that this has created a similar performance gain. I'll look into it.

    At least, the class still makes sense for users of Unity versions below 3.0.
    [/edit]

    [edit2]
    If you're rolling your own class, you may want to try and see what happens if you make it crash while writing data to disk or when setting a value in memory (e.g. by throwing exceptions at random). Our class isn't that robust and may cause the game to crash when trying to deserialize. It's not very likely to happen (depending on the usage), but you may want to look into this. I don't know whether there's an issue with the built-in class here.

    An other thing is that when you're doing a free-to-play game, you'll need to store some values more securely - we're not doing any encryption or other security measures as we only cared about performance. I'm not sure whether the normal PlayerPrefs class is storing data in a secure way. Especially on Android, it's very easy to look at the files and modify a value.

    A developer sent me an improved version of the class that does use encryption a few weeks ago. This class still isn't 100% secure, but it does provide a first hurdle. I may upload this to our blog later on.

    Also note that players who are trying to bypass your security may not be the kind of players that would be paying in a free-to-play game anyway.
    [/edit2]
     
    Last edited: Aug 17, 2012