成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Android的SP存儲,效率探究

企業動態
對于 SharedPreferences(以下簡稱SP),相信 Android 開發們,都不會陌生。無非是 Android 系統提供的一個以 Key-Value 鍵值對形式的存儲方式。如果需要獲取數據,SP 中提供了對應的getXxx() 方法,如果需要存儲數據,只需要拿到 Editor 對象,在 Editor 對象中,也提供了對應的 putXxx() 方法,在操作完成之后,調用 commit() 或者 apply() 即可。

[[199471]]

一、前言

對于 SharedPreferences(以下簡稱SP),相信 Android 開發們,都不會陌生。無非是 Android 系統提供的一個以 Key-Value 鍵值對形式的存儲方式。如果需要獲取數據,SP 中提供了對應的getXxx() 方法,如果需要存儲數據,只需要拿到 Editor 對象,在 Editor 對象中,也提供了對應的 putXxx() 方法,在操作完成之后,調用 commit() 或者 apply() 即可。

那么 commit() 和 apply() 有什么區別?就是本篇文章的主題。

二、從文檔上看區別

SharedPreferences 就是一個接口,其實現類是SharedPreferencesImpl 。

關于 commit() 和 apply() 的描述,在 SharedPreferences 中,下面先看看文檔中對它的說明。

從文檔中可以看出一些區別:

  1. apply() 沒有返回值,而 commit() 是有返回值的,返回值標識著是否執行成功。
  2. apply() 的操作是原子提交到內存中,然后以異步的方式保存到磁盤上,而 commit() 完全是以同步的方式將數據保存到磁盤上。
  3. apply() 因為沒有返回值,所以不會提示任何失敗。只需要調用即可。
  4. 無論是 apply() 還是 commit() ,如果同時被操作了,以***一次操作為準。

獲取SP這個對象的方式,是使用:

  1. Context.getSharedPreferences() 

所以在同一進程中,SP 對象是以單例的形式存在的,就不需要考慮有沖突的問題。但是因為 apply() 和 commit() 的差異性,如果對提交結果不關心的話,推薦使用 apply() ,如果需要確保保存成功之后,才繼續進行后續的操作,推薦使用 commit()。

三、從代碼中看區別

雖然從文檔中,完全就可以了解清楚 SP 中,commit() 和 apply() 的具體區別和使用場景。但是作為一個有情懷的碼農,還是需要再往深了一層挖挖,一探究竟。

之前提到,SharedPreferences 接口的實現類是SharedPreferencesImpl 。那么就繼續看看 apply() 和 commit() 的具體實現。

apply() :

commit():

對比發現 commit() 的實現非常的簡單,并且在 SP 中,是通過 enqueueDiskWrite() 方法來控制是否是異步操作的。

下面看看 enqueueDiskWrite() 方法的實現。

從注釋里可以看到,如果 enqueueDiskWrite() 的第二個參數為 null 的話,則會變成同步操作。而正是因為在 commit() 中是同步操作,commit() 才可以拿到操作是否正確的結果。

具體將數據持久化到硬盤上的操作,是調用了 writeToFile() 方法,無非就是一些對文件讀寫的操作和 XML 的處理,這個就不再這里繼續探討了,有興趣的可以自己看看源碼。

四、從效率上看問題

看了源碼更印證了之前的結論。

再從效率上看看 SP ,從 SP 提供的接口上看,get 操作應該只是去獲取,這個就像從一個單例的對象中,獲取一個數據一樣,從效率上看應該是不存在什么損耗的。那么從存儲的角度,去分析一下效率的問題。

這個先上結論,再來分析一下問題。寫了一個簡單的 demo :

A 操作和 B 操作,在代碼邏輯上應該是一樣的,都是想 SP 中寫入100 次不同字段的數據,區別只是在于,A操作每次都去獲取新的 Editor ,而 B 操作是只使用一個 Eidtor 去存儲。兩個操作都分別執行兩次。

可以看出來,使用 commit() 的方式,如果每次都使用 sp.edit() 方法獲取一個新的 Editor 的話,新建和修改的執行效率差了非常的大。也就是說,存儲一個從來沒有用過的 Key ,和修改一個已經存在的 Key,在效率上是有差別的。

然后把之前的例子中, commit() 修改成 apply() ,這里就不貼代碼了。再來看看執行結果,當然在運行前需要先清空數據。這里把 A 操作和 B 操作分別執行了 4 次。

從執行結果可以發現,使用 apply() 因為是異步操作,基本上是不耗費時間的,效率上都是 OK 的。從這個結論上來看,apply() 影響效率的地方,在 sp.edit() 方法。

那么,再看看 edit() 方法是如何實現的:

可以看出來,在 edit() 中是有 synchronized 這個同步鎖來保證線程安全的,縱觀 EditorImpl 的實現,可以看到大部分操作都是有同步鎖的,但是只鎖了 (this) ,也就是只對當前對象有效,而 edit() 方法是每次都會去重新 new 一個 EditorImpl() 這個Eidtor 接口的實現類。所以效率就應該是被這里影響到了。

、結論

既然已經分析了 SP 的文檔說明和代碼實現,那么就可以分析出一些SP 效率相關的結論。

edit() 是有效率影響的,所以不要在循環中去調用此方法,***將 edit() 方法獲取的 Editor 對象方在循環之外,在循環中共用同一個 Editor() 對象進行操作。

commit() 的時候,「new-key」和「update-key」的效率是有差別的,但是有返回結果。

apply() 是異步操作,對效率的影響,基本上是 ms 級的,可以忽略不記。

【本文為51CTO專欄作者“張旸”的原創稿件,轉載請通過微信公眾號聯系作者獲取授權】

戳這里,看該作者更多好文

責任編輯:武曉燕 來源: 51CTO專欄
相關推薦

2011-08-15 16:16:09

SQL Server存儲過程sp_MSforeac

2015-06-10 10:02:40

云存儲虛擬化存儲模型

2017-05-18 15:02:36

AndroidGC原理JVM內存回收

2013-08-21 09:58:05

2009-11-24 14:22:55

存儲路由技術

2018-02-05 08:26:11

大數據云存儲安全性

2018-05-24 08:47:15

數據存儲技巧

2015-06-15 11:15:32

雅虎Ceph云存儲

2009-02-01 13:39:31

磁盤陣列數據中心SATA

2013-06-04 15:41:31

iOS開發移動開發block

2010-08-02 16:51:54

2017-03-06 16:13:41

深度學習人工智能

2017-01-12 19:28:06

V5030F 存儲

2011-04-13 16:48:56

索引數據庫

2010-09-29 15:11:34

J2MEAndroid

2014-08-26 10:51:44

數據存儲

2023-11-10 11:02:28

Android10分區存儲

2014-08-26 10:04:51

數據存儲

2017-10-27 09:01:26

Oracle存儲管理

2024-05-08 08:56:09

GreatSQL內存宏定義
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美乱做爰xxxⅹ久久久 | 久久大陆 | 国产精品一区一区三区 | 九九热免费在线观看 | 91电影院| 精品三级在线观看 | 国产精品自拍视频 | 午夜电影网 | 91免费在线| 中文字幕一二三 | 欧美日韩美女 | 日韩超碰在线 | 午夜精品久久久久久久99黑人 | 99久久婷婷国产综合精品首页 | 亚洲天堂精品久久 | 午夜影院在线观看免费 | 91在线一区二区三区 | 国产精品大片 | 亚洲国产成人精品久久久国产成人一区 | 亚洲中字在线 | 欧美人妖网站 | 精品久久久久久亚洲综合网 | 欧美性久久 | 欧美日韩精品综合 | 99亚洲综合| 日韩不卡一区二区 | 久久av一区二区三区 | 亚洲国产精品99久久久久久久久 | 国产精品久久久久久久久久久免费看 | 国产精品五月天 | 久久国产精品免费一区二区三区 | 国产网站在线播放 | 精品亚洲一区二区 | 一级片av | 国产精品99久久久久久大便 | 成人在线视频免费看 | 范冰冰一级做a爰片久久毛片 | 日日干夜夜操天天操 | 中文字幕一区二区视频 | 欧洲一区二区三区 | 亚洲视频免费观看 |