真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

Android優(yōu)化之存儲優(yōu)化的實現(xiàn)

交換數(shù)據(jù)格式

濱城網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián)建站,濱城網(wǎng)站設(shè)計制作,有大型網(wǎng)站制作公司豐富經(jīng)驗。已為濱城成百上千提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站建設(shè)公司要多少錢,請找那個售后服務(wù)好的濱城做網(wǎng)站的公司定做!

Google 推出的 Protocal Buffers 是一種更輕便高效的存儲結(jié)構(gòu),但消耗內(nèi)存較大。

FlatBuffers 同樣由 Google 推出,專注性能,適合移動端。占用存儲比 Protocal 要大。

SharePreferences 優(yōu)化

  • 當(dāng) SharedPreferences 文件還沒有被加載到內(nèi)存時,調(diào)用 getSharedPreferences 方法會初始化文件并讀入內(nèi)存,這容易導(dǎo)致 耗時更長。
  • Editor 的 commit 或者 apply 方法的區(qū)別在于同步寫入和異步 寫入,以及是否需要返回值。在不需要返回值的情況下,使用 apply 方法可以極大提高性能。
  • SharedPreferences 類 中的 commitToMemory() 會鎖定 SharedPreference 對象,put() 和 getEditor() 方法會鎖定 Editor 對象,在寫入磁盤時更會鎖定一個寫入鎖。因此,最好的優(yōu)化方法就是避免頻繁地讀寫 SharedPreferences,減少無謂的調(diào)用。對于 SharedPreferences 的批量操作,最好先獲取一個 editor 進(jìn)行批量操作,然后調(diào)用 apply 方法。

Bitmap 解碼

  • 4.4 以上 decodeFile 內(nèi)部沒有使用緩存,效率不高。要使用 decodeStream,同時傳入的文件流為 BufferedInputStream。
  • decodeResource 同樣存在性能問題,用 decodeResourceStream。

數(shù)據(jù)庫優(yōu)化

1、使用 StringBuilder 代替 String

2、查詢時返回更少的結(jié)果集及更少的字段

查詢時只取需要的字段和結(jié)果集,更多的結(jié)果集會消耗更多的時間及內(nèi)存,更多的字段會導(dǎo)致更多的內(nèi)存消耗。

3、少用 cursor.getColumnIndex

根據(jù)性能調(diào)優(yōu)過程中的觀察 cursor.getColumnIndex 的時間消耗跟 cursor.getInt 相差無幾。可以在建表的時候用 static 變量記住某列的 index,直接調(diào)用相應(yīng) index 而不是每次查詢。

4、異步線程

Android 中數(shù)據(jù)不多時表查詢可能耗時不多,不會導(dǎo)致 ANR,不過大于 100ms 時同樣會讓用戶感覺到延時和卡頓,可以放在線程中運行,但 sqlite 在并發(fā)方面存在局限,多線程控制較麻煩,這時候可使用單線程池,在任務(wù)中執(zhí)行 db 操作,通過 handler 返回結(jié)果和 UI 線程交互,既不會影響 UI 線程,同時也能防止并發(fā)帶來的異常。

5、SQLiteOpenHelper 維持一個單例

因為 SQLite 對多線程的支持并不是很完善,如果兩個線程同時操作數(shù)據(jù)庫,因為數(shù)據(jù)庫被另一個線程占用, 這種情況下會報“Database is locked” 的異常。所以在數(shù)據(jù)庫管理類中使用單例模式,就可以保證無論在哪個線程中獲取數(shù)據(jù)庫對象,都是同一個。

最好的方法是所有的數(shù)據(jù)庫操作統(tǒng)一到同一個線程隊列管理,而業(yè)務(wù)層使用緩存同步,這樣可以完全避免多線程操作數(shù)據(jù)庫導(dǎo)致的不同步和死鎖問題。

6、Application 中初始化

  • 使用 Application 的 Context 創(chuàng)建數(shù)據(jù)庫,在 Application 生命周期結(jié)束時再關(guān)閉。
  • 在應(yīng)用啟動過程中最先初始化完數(shù)據(jù)庫,避免進(jìn)入應(yīng)用后再初始化導(dǎo)致相關(guān)操作時間變長。

7、少用 AUTOINCREMENT

主鍵加上 AUTOINCREMENT 后,可以保證主鍵嚴(yán)格遞增,但并不能保證每次都加 1,因為在插入失敗后,失敗的行號不會被復(fù)用,會造成主鍵有間隔,繼而使 INSERT 耗時 1 倍以上。

這個 AUTOINCREMENT 關(guān)鍵詞會增加 CPU,內(nèi)存,磁盤空間和磁盤 I/O 的負(fù)擔(dān),所以 盡量不要用,除非必需。通常情況下都不是必需的。

事務(wù)

使用事務(wù)的兩大好處是原子提交和更優(yōu)性能:

  • 原子提交:意味著同一事務(wù)內(nèi)的所有修改要么都完成要么都不做,如果某個修改失敗,會自動回滾使得所有修改不生效。
  • 更優(yōu)性能:Sqlite 默認(rèn)會為每個插入、更新操作創(chuàng)建一個事務(wù),并且在每次插入、更新后立即提交。這樣如果連續(xù)插入 100 次數(shù)據(jù)實際是創(chuàng)建事務(wù)、執(zhí)行語句、提交這個過程被重復(fù)執(zhí)行了 100 次。如果顯式的創(chuàng)建事務(wù),這個過程只做一次,通過這種一次性事務(wù)可以使得性能大幅提升。尤其當(dāng)數(shù)據(jù)庫位于 sd 卡時,時間上能節(jié)省兩個數(shù)量級左右。

主要三個方法:beginTransaction,setTransactionSuccessful,endTransaction。

SQLiteStatement

使用 Android 系統(tǒng)提供的 SQLiteStatement 來插入數(shù)據(jù),在性能上有一定的提高,并且也解決了 SQL 注入的問題。

SQLiteStatement statement = dbOpenHelper.getWritableDatabase().compileStatement("INSERT INTO EMPERORS(name, dynasty, start_year) values(?,?,?)"); 
statement.clearBindings();
statement.bindString(1, "Max"); 
statement.bindString(2, "Luk"); 
statement.bindString(3, "1998"); 
statement.executeInsert();

SQLiteStatement 只能插入一個表中的數(shù)據(jù),在插入前要清除上一次的數(shù)據(jù)。

索引

索引就像書本的目錄,目錄可以快速找到所在頁數(shù),數(shù)據(jù)庫中索引可以幫助快速找到數(shù)據(jù),而不用全表掃描,合適的索引可以大大提高數(shù)據(jù)庫查詢的效率。

優(yōu)點:大大加快了數(shù)據(jù)庫檢索的速度,包括對單表查詢、連表查詢、分組查詢、排序查詢。經(jīng)常是一到兩個數(shù)量級的性能提升,且隨著數(shù)據(jù)數(shù)量級增長。

缺點:

  • 索引的創(chuàng)建和維護(hù)存在消耗,索引會占用物理空間,且隨著數(shù)據(jù)量的增加而增加。
  • 在對數(shù)據(jù)庫進(jìn)行增刪改時需要維護(hù)索引,所以會對增刪改的性能存在影響。

分類

1、直接創(chuàng)建索引和間接創(chuàng)建索引

  • 直接創(chuàng)建: 使用 sql 語句創(chuàng)建,Android 中可以在 SQLiteOpenHelper 的 onCreate 或是 onUpgrade 中直接 excuSql 創(chuàng)建語句,如 CREATE INDEX mycolumn_index ON mytable (myclumn)
  • 間接創(chuàng)建: 定義主鍵約束或者唯一性鍵約束,可以間接創(chuàng)建索引,主鍵默認(rèn)為唯一索引。

2、普通索引和唯一性索引

  • 普通索引:CREATEINDEXmycolumn_indexONmytable(myclumn)
  • 唯一性索引:保證在索引列中的全部數(shù)據(jù)是唯一的,對聚簇索引和非聚簇索引都可以使用,語句為 CREATE UNIQUE COUSTERED INDEX myclumn_cindex ON mytable(mycolumn)

3、單個索引和復(fù)合索引

  • 單個索引:索引建立語句中僅包含單個字段,如上面的普通索引和唯一性索引創(chuàng)建示例。
  • 復(fù)合索引:又叫組合索引,在索引建立語句中同時包含多個字段,如 CREATEINDEXname_indexONusername(firstname,lastname),其中 firstname 為前導(dǎo)列。

4、聚簇索引和非聚簇索引 (聚集索引,群集索引)

  • 聚簇索引:物理索引,與基表的物理順序相同,數(shù)據(jù)值的順序總是按照順序排列,如 CREATE CLUSTERED INDEX mycolumn_cindex ON mytable(mycolumn) WITH ALLOW_DUP_ROW,其中 WITH ALLOW_DUP_ROW 表示允許有重復(fù)記錄的聚簇索引
  • 非聚簇索引:CREATEUNCLUSTEREDINDEXmycolumn_cindexONmytable(mycolumn),索引默認(rèn)為非聚簇索引

使用場景

  • 當(dāng)某字段數(shù)據(jù)更新頻率較低,查詢頻率較高,經(jīng)常有范圍查詢 (>, <, =,>=, <=) order by、group by 發(fā)生時建議使用索引。并且選擇度(一個字段中唯一值的數(shù)量 / 總的數(shù)量)越大,建索引越有優(yōu)勢
  • 經(jīng)常同時存取多列,且每列都含有重復(fù)值可考慮建立復(fù)合索引

使用規(guī)則

  1. 對于復(fù)合索引,把使用最頻繁的列做為前導(dǎo)列 (索引中第一個字段)。如果查詢時前導(dǎo)列不在查詢條件中則該復(fù)合索引不會被使用。如 create unique index PK_GRADE_CLASS on student (grade, class),select * from student where class = 2 未使用到索引,select * from dept where grade = 3 使用到了索引
  2. 避免對索引列進(jìn)行計算,對 where 子句列的任何計算如果不能被編譯優(yōu)化,都會導(dǎo)致查詢時索引失效 select * from student where tochar(grade)='2
  3. 比較值避免使用 NULL
  4. 多表查詢時要注意是選擇合適的表做為內(nèi)表。連接條件要充份考慮帶有索引的表、行數(shù)多的表,內(nèi)外表的選擇可由公式:外層表中的匹配行數(shù) * 內(nèi)層表中每一次查找的次數(shù)確定,乘積最小為最佳方案。實際多表操作在被實際執(zhí)行前,查詢優(yōu)化器會根據(jù)連接條件,列出幾組可能的連接方案并從中找出系統(tǒng)開銷最小的最佳方案
  5. 查詢列與索引列次序一致
  6. 用多表連接代替 EXISTS 子句
  7. 把過濾記錄數(shù)最多的條件放在最前面
  8. 善于使用存儲過程,它使 sql 變得更加靈活和高效 (Sqlite 不支持存儲過程)

其它通用優(yōu)化

  1. 經(jīng)常用的數(shù)據(jù)讀取后緩存起來,以免多次重復(fù)讀寫造成“寫入放大”
  2. 子線程讀寫數(shù)據(jù)
  3. ObjectOutputStream 在序列化磁盤時,會把內(nèi)存中的每個對象保存到磁盤,在保存對象的 時候,每個數(shù)據(jù)成員會帶來一次 I/O 操作。在 ObjectOutputStream 上面再封裝一個輸出流 ByteArrayOutputStream 或 BufferedOutputStream,先將對象序列化后的信息寫到緩存區(qū)中,然后再一次性地寫到磁盤上;相應(yīng)的,用 ByteArrayInputStream 或 BufferedInputStream 替代 ObjectInputStream。
  4. 合理選擇緩沖區(qū) Buffer 的大小。太小導(dǎo)致 I/O 操作次數(shù)增多,太大導(dǎo)致申請時間變長。比如 4-8 KB。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。


本文名稱:Android優(yōu)化之存儲優(yōu)化的實現(xiàn)
文章源于:http://weahome.cn/article/jssegs.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部