Android Benchmark 运行方法
使用 Android Studio 打开 android
目录工程,其中可以找到 benchmark 模块。Benchmark 用 Instrumented Unit Test 实现,分开不同用例,要执行对应的用例,右键点击对应的测试类,选择 "Run 'xxx'" 即可在手机上运行。
添加自己的 Benchmark Case
如果需要增加自己的测试项目(比如使用不同的库,或不同的配置参数),派生对应的测试基类并实现其中打开、查询等接口,即可快速实现新的测试用例。具体可以参见 SingleThreadedTest
(基类)和 WCDBSingleThreadedTest
、FrameworkSingleThreadedTest
(派生测试类)。
Single-threaded Test
测试单线程 DB 读写性能,有以下用例:
- Create: 打开 DB ,初始化并创建一个数据表和一个 Index。加密 DB 会在此时初始化密钥。
- Insert Transaction: 打开事务,重复执行
INSERT
19,000 次,提交事务。 - Insert Separated: 不使用事务,重复执行
INSERT
1,000 次。 - Insert Rollback: 打开事务,重复执行
INSERT
1,000 次,回滚事务。 - Update One SQL: 执行
UPDATE
语句,一次修改 10,000 条记录。 - Update Transaction: 打开事务,重复执行
UPDATE
10,000 次,每次修改一条记录,提交事务。 - Update Separated: 不使用事务,重复执行
UPDATE
1,000 次,每次修改一条记录。 - Query One: 使用
SELECT
语句每次查询一条记录,重复执行 10,000 次。 - Query Fill: 使用
SELECT
语句一次性查询 10,000 条记录,遍历 Cursor 读出所有记录。 - Delete One SQL: 执行
DELETE
语句,一次性删除 5,000 条记录。 - Delete Transaction: 打开事务,重复执行
DELETE
5,000 次,每次删除一条记录,提交事务。 Delete Separated: 不使用事务,重复执行
DELETE
1,000 次,每次删除一条记录。
以上用例分别在同一台手机上基于不同库(WCDB、Android 原生、SQLCipher Android)和不同配置(是否WAL、是否加密)多次执行,取耗时平均值,单位毫秒(程序采集的是纳秒,统计时转换为毫秒)。Framework: 对应手机上的 Android 原生框架(根据手机不同有不同版本)
- WCDB: WCDB Android
- SQLCipher: SQLCipher Android
- (E): 加密
- (W): WAL 模式
Nexus 5 Android 6.0.1 (armeabi-v7a)
Create | Insert Transaction | Insert Separated | Insert Rollback | Update One SQL | Update Transaction | |
---|---|---|---|---|---|---|
Framework | 79 | 1525 | 11255 | 94 | 128 | 750 |
Framework(W) | 66 | 1588 | 1739 | 76 | 128 | 739 |
SQLCipher | 34 | 1714 | 19083 | 96 | 121 | 824 |
SQLCipher(E) | 388 | 1774 | 15948 | 94 | 190 | 892 |
WCDB | 33 | 1769 | 9916 | 104 | 121 | 849 |
WCDB(E) | 352 | 1815 | 10543 | 106 | 150 | 901 |
WCDB(W) | 35 | 1781 | 1624 | 91 | 128 | 865 |
WCDB(EW) | 327 | 1829 | 1842 | 88 | 126 | 875 |
Update Separated | Query One | Query Fill | Delete One SQL | Delete Transaction | Delete Separated | |
---|---|---|---|---|---|---|
Framework | 9480 | 3798 | 385 | 71 | 340 | 10784 |
Framework(W) | 1773 | 2746 | 393 | 44 | 301 | 1661 |
SQLCipher | 14307 | 4260 | 817 | 55 | 327 | 18645 |
SQLCipher(E) | 14302 | 4245 | 815 | 120 | 421 | 14922 |
WCDB | 8860 | 3053 | 325 | 50 | 358 | 9579 |
WCDB(E) | 9314 | 3093 | 321 | 81 | 418 | 10222 |
WCDB(W) | 1704 | 2099 | 328 | 66 | 343 | 1576 |
WCDB(EW) | 1778 | 2124 | 327 | 47 | 398 | 1718 |
Nexus 5X Android 7.1.2 (arm64-v8a)
Create | Insert Transaction | Insert Separated | Insert Rollback | Update One SQL | Update Transaction | |
---|---|---|---|---|---|---|
Framework | 49 | 1081 | 7121 | 91 | 71 | 510 |
Framework(W) | 53 | 1112 | 1789 | 80 | 69 | 497 |
SQLCipher | 28 | 857 | 15208 | 75 | 73 | 397 |
SQLCipher(E) | 303 | 971 | 16900 | 72 | 115 | 444 |
WCDB | 28 | 1027 | 6601 | 88 | 80 | 492 |
WCDB(E) | 243 | 1093 | 17283 | 94 | 91 | 546 |
WCDB(W) | 36 | 1077 | 1491 | 73 | 68 | 475 |
WCDB(EW) | 212 | 1051 | 3574 | 76 | 85 | 492 |
Update Separated | Query One | Query Fill | Delete One SQL | Delete Transaction | Delete Separated | |
---|---|---|---|---|---|---|
Framework | 8821 | 3385 | 151 | 46 | 251 | 9905 |
Framework(W) | 2907 | 2337 | 153 | 27 | 198 | 2962 |
SQLCipher | 11161 | 3924 | 441 | 54 | 227 | 18222 |
SQLCipher(E) | 14467 | 4137 | 459 | 112 | 307 | 17877 |
WCDB | 7084 | 1886 | 116 | 47 | 234 | 18323 |
WCDB(E) | 12065 | 1970 | 117 | 56 | 248 | 12981 |
WCDB(W) | 1321 | 1081 | 110 | 41 | 206 | 2579 |
WCDB(EW) | 2930 | 1015 | 110 | 31 | 229 | 3108 |
Concurrent Test
测试多线程并发访问性能,有以下用例:
- WWWW (transaction): 4个并发写线程,各自打开事务,插入 5,000 条记录,然后提交事务。
- WWWW (separated): 4个并发写线程,不使用事务,插入 500 条记录。
- WWRR (batch): 4个并发线程,2个写线程各使用单条
UPDATE
语句修改 5,000 条记录,2个读线程各一次性查询 5,000 条记录。 - WRRR: 4个并发线程,3个读线程分别一次性查询 5,000 条记录和一次查询一条记录重复 5,000 次,1个写线程一次性修改 5,000 条记录。
- RRRR: 4个并发读线程,分别一次性查询 5,000 条记录和一次查询一条记录重复 5,000 次。
同样在不同库不同配置下跑,4个线程同时开始到全部结束计时,多次执行去平均值,单位毫秒。
Nexus 5 Android 6.0.1 (armeabi-v7a)
WWWW (transaction) | WWWW (separated) | WWRR (batch) | WRRR | RRRR | |
---|---|---|---|---|---|
Framework | 1955 | 22204 | 393 | 3608 | 3603 |
Framework(W) | 1835 | 3664 | 285 | 1792 | 1850 |
SQLCipher | 2209 | 49185 | 477 | 3976 | 4122 |
SQLCipher(E) | 2287 | 41337 | 547 | 4006 | 4016 |
WCDB | 2131 | 21666 | 496 | 4185 | 4083 |
WCDB(E) | 2157 | 23454 | 368 | 3744 | 3611 |
WCDB(W) | 2090 | 3766 | 264 | 1391 | 1359 |
WCDB(EW) | 2198 | 4818 | 959 | 1685 | 1449 |