Read speed of SharedPreferences
Asked Answered
D

5

40

How fast are SharedPreferences? Is there a way to put them in memory for reading? I have a small amount of data that a ListView has to query to display each cell, and I'm worried that a call to flash memory will be too slow. I'm not worried about write speed, as writes will happen infrequently. I'm considering just using a JSON object to persist the data instead of SharedPreferences. Any thoughts?

Dentalium answered 2/10, 2013 at 23:10 Comment(1)
SharedPreferences is essentially a xml-file residing in the app "sandbox" storage. It can be accessed and viewed through ADB.Landon
W
64

Is there a way to put them in memory for reading?

They are in memory, after the first reference. The first time you retrieve a specific SharedPreferences (e.g., PreferenceManager.getDefaultSharedPreferences()), the data is loaded from disk, and kept around.

Wop answered 2/10, 2013 at 23:18 Comment(9)
you say, the whole saved data in SharedPreferences will be loaded once you get instance of PreferenceManager.getDefaultSharedPreferences() ???Inequity
@MoshErsan: Yes. The SharedPreferences is held in a static HashMap of SharedPreferences in ContextImpl. It will remain there until the process is terminated. See sSharedPrefs in github.com/android/platform_frameworks_base/blob/master/core/…Wop
what is the benefit of doing it like this?!!Inequity
@MoshErsan: Among other things, it ensures that all components of your app, asking for the same SharedPreferences, get the actual same SharedPreferences instance, and so they cannot get out of sync with each other.Wop
I was reading SharedPreferencesImpl->startLoadFromDisk, in this case if we saved a big data in it, it may cause OOE.Inequity
@MoshErsan: Correct. SharedPreferences should be small.Wop
@MohammadErsan for some data it's better to use database (SQLite) and SharedPreferences for some settings. I don't think your apps have a lot of settingsAdenoid
bad answer, you still have to load from disk, even you have the reference. Gosh!Wheresoever
@Devon: "you still have to load from disk" -- not according to the source code and the source code. Preferences and their values are cached.Wop
G
19

My advice is to test your performance first, and then start worrying about speed. In general, you'll be happier with an app that prioritizes maintainability as well as speed. When engineers start out to achieve performance before they get the app stable, the result is an app that runs a bit faster but has lots of bugs.

Graehme answered 3/10, 2013 at 1:15 Comment(0)
D
17

According to this link, getSharedPreferences is not that much heavy because it opens file only when you call getSharedPreferences first time:

// There are 1000 String values in preferences

SharedPreferences first = context.getSharedPreferences("com.example.app", Context.MODE_PRIVATE);
// call time = 4 milliseconds

SharedPreferences second = context.getSharedPreferences("com.example.app", Context.MODE_PRIVATE);
// call time = 0 milliseconds

SharedPreferences third = context.getSharedPreferences("com.example.app", Context.MODE_PRIVATE);
// call time = 0 milliseconds

But using get methods will take some time for the first time you call it:

first.getString("key", null)
// call time = 147 milliseconds

first.getString("key", null)
// call time = 0 milliseconds

second.getString("key", null)
// call time = 0 milliseconds

third.getString("key", null)
// call time = 0 milliseconds 
Deidredeific answered 8/7, 2020 at 15:20 Comment(2)
So it looks like a "lazy“ implementation the loading happens on first get.Vally
amazing article! thanks for sharingTripartite
M
0

Another benchmark for those interested in larger files. The snippet below run on a 2013(?) Samsung SMT-350 tablet (1.2 GHz Quad-Core, Qualcomm) revealed:

  • About 80 seconds to create 10000 7k strings
  • About 3.5 seconds to 'open' (getSharedPreferences) the 70mb file
  • About 1/10ms to read any 7k string once the SP was open

Note: the file creation crashed at 5500, but continued without problem. I am NOT recommending the use of 70MB SPs, this was for an unlikely edge case test, and 100x over-test.

        G.logTime("MAKE HUGE FILE", true);
        String sevenKString = App.getAsset(this, "sample_map.txt");
        SharedPreferences.Editor spf = getSharedPreferences("TEST", Context.MODE_PRIVATE).edit();
        G.logTime("SP OPEN", false);
        for (Integer i = 0; i < 10000; i++) {
            spf.putString(i.toString(), sevenKString);
            spf.apply();
            G.logTime("SP ADD " + i.toString() + " (" + (7 * i) + ")", false);
        }

        G.logTime("SP OPEN", true);
        SharedPreferences sp = getSharedPreferences("TEST", Context.MODE_PRIVATE);
        for (Integer i = 1; i < 10000; i += 10) {
            file = sp.getString(i.toString(), null);
            G.logTime("SP READ = " + i.toString(), false);
        }
Milstone answered 18/3, 2023 at 22:20 Comment(0)
R
-1

I have a small amount of data that a ListView has to query to display each cell

Can't you make a Singleton, a common class and read it from there from second time? I would do that.

Retainer answered 2/10, 2013 at 23:22 Comment(1)
There is no need to increase shared global state via Singletons. Android already has solutions for global state management via SharedPreferences and Bundles. It is enough. You should eliminate global state as much as you canTodo

© 2022 - 2024 — McMap. All rights reserved.