【腾讯Bugly干货分享】微信iOS SQLite源码优化实践分享实录

sqlite多进程并发读写模式下,返回SQLITE_BUSY错误的处理方法 SQLite作为一款小型的嵌入式数据库,本身没有提供复杂的锁定机制,无法内部管理多路并发下的数据操作同步问题,更谈不上优化,所以涉及到多路并发的情况,需要外部进行读写锁控制,否则SQLite会返回SQLITE_BUSY错误,以驳回相关请求,这是由于使用当前连接访问数据时,要申请相应级别的锁,而各个级别的锁有些是互斥的,当申请不到锁时就会返回这个错误。这时只要稍等片刻,等其它连接的操作处理完,释放了 阅读详情

本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57b6a449433221be01499486

Dev Club 是一个交流移动开发技术,结交朋友,扩展人脉的社群,成员都是经过审核的移动开发工程师。每周都会举行嘉宾分享,话题讨论等活动。

本期,我们邀请了腾讯 WXG iOS 开发工程师——张三华,为大家分享《微信 iOS SQLite 源码优化实践》。

分享内容简介:

SQLite是微信iOS选用的数据库,随着微信iOS客户端业务的增长,在重度用户的场景下,性能瓶颈逐渐显现。靠单纯地修改SQLite的参数配置,已经不能彻底解决问题,因此我们尝试从源码开始做深入的优化。

内容大体框架:

  1. SQLite对于多线程的处理和不足及微信的优化
  2. SQLite在I/O上可压榨的性能
  3. 其他细节优化

下面是本期分享内容整理


Hello,大家好,我是张三华,目前在微信主要负责 iOS 的基础优化工作。第一次进行这种微信群分享,可能准备的不是太充分。若有任何疑问,欢迎在分享结束后提问。

下面开始我们今天的分享。

引言

SQLite 是我们在移动端常用的数据库,微信也是基于它封装了一层 ObjC 接口。我们知道,微信里消息的收发是很频繁的,尤其是对于重度用户,这对于数据库的多线程并发和 I/O 是很大的挑战。

通常对这部分做优化,有两种方式:

  • 一是修改 SQLite 的参数,如 Cache Size 等
  • 二是改业务层调用,如主线程操作 dispatch 到子线程。

然而,前者有明显的瓶颈,后者则是个 endless 的工作。我们希望能一劳永逸地解决同类问题。这就是我们本次所要分享的优化。

1. 多线程并发优化

1.1 SQLite 多句柄方案

我们先讲 SQLite 所提供的多线程并发方案。它对这方面的支持做的很不错,在使用上,只需

  1. 开启句柄多线程支持的配置 PRAGMA SQLITE_THREADSAFE=2
  2. 确保同一个句柄同一时间只有一个线程在操作
  3. (可选)开启 WAL 模式 PRAGMA journal_mode=WAL

此时写操作会先 append 到 wal 文件末尾,而不是直接覆盖旧数据。而读操作开始时,会记下当前的 WAL 文件状态,并且只访问在此之前的数据。这就确保了多线程读与读、读与写之间可以并发地进行。

1.2 Busy Retry 方案

而写与写之间仍会互相阻塞。SQLite 提供了 Busy Retry 的方案,即发生阻塞时,会触发 Busy Handler,此时可以让线程休眠一段时间后,重新尝试操作。重试一定次数依然失败后,则返回 SQLITE_BUSY 错误码。

下面这段代码是 SQLite 默认的 Busy Handler

1.3 Busy Retry 方案的不足

上面介绍了 SQLite 多线程并发方案,接下来我们把焦点放在 Busy Retry 这个方案的不足上。

Busy Retry 的方案虽然基本能解决问题,但对性能的压榨做的不够极致。在 Retry 过程中,休眠时间的长短和重试次数,是决定性能和操作成功率的关键。

然而,它们的最优值,因不同操作不同场景而不同。若休眠时间太短或重试次数太多,会空耗 CPU 的资源;若休眠时间过长,会造成等待的时间太长;若重试次数太少,则会降低操作的成功率。如下图

可以看到

  • CPU空转那段,线程一操作还没结束,这里空耗了 CPU 的资源
  • 线程闲置那段,线程一已经结束,而线程二仍在等待,空耗了时间

对于这个的优化,简单的方法可以是修改休眠时间,尽最大限度缩短以上两段空耗的资源。

我们通过 A/B Test 对不同休眠时间进行了实验,得到了如下的结果

可以看到,倘若休眠时间与重试成功率的关系,按照绿色的曲线进行分布,那么 p 点的值也不失为该方案的一个次优解。然而不同业务和操作的需求,还是有很大的不同的。

既然 SQLite 的方案不行,我们就要开始往深层探索新的可能性了。

1.4 SQLite 中控制并发相关的原理

SQLite是一个适配不同平台的数据库,不仅支持多线程并发,还支持多进程并发。它的核心逻辑可以分为两部分:

  • Core 层。包括了接口层、编译器和虚拟机。通过接口传入 SQL 语句,由编译器编译SQL生成虚拟机的操作码 opcode。而虚拟机是基于生成的操作码,控制 Backend 的行为。
  • Backend 层。由 B-Tree、Pager、OS 三部分组成,实现了数据库的存取数据的主要逻辑。

在架构最底端的 OS 层是对不同操作系统的系统调用的抽象层。它实现了一个 VFS(Virtual File System),将 OS 层的接口在编译时映射到对应操作系统的系统调用。锁的实现也是在这里进行的。

SQLite 通过两个锁来控制并发。第一个锁对应 DB 文件,通过5种状态进行管理;第二个锁对应WAL文件,通过修改一个 16-bit 的 unsigned short int 的每一个 bit 进行管理。尽管锁的逻辑有一些复杂,但此处并不需关心。这两种锁最终都落在 OS 层的 sqlite3OsLock、sqlite3OsUnlock 和 sqlite3OsShmLock 上具体实现。

它们在锁的实现比较类似。以 lock 操作在 iOS 上的实现为例:

  1. 通过 pthread_mutex_lock 进行线程锁,防止其他线程介入。然后比较状态量,若当前状态不可跳转,则返回 SQLITE_BUSY
  2. 通过 fcntl 进行文件锁,防止其他进程介入。若锁失败,则返回 SQLITE_BUSY

而 SQLite 选择 Busy Retry 的方案的原因也正是在此

文件锁没有线程锁类似 pthread_cond_signal 的通知机制。当一个进程的数据库操作结束时,无法通过锁来第一时间通知到其他进程进行重试。因此只能退而求其次,通过多次休眠来进行尝试。

1.5 新的方案

搞清楚了 SQLite 并发的实现,我们就是可以开始改造了。

我们知道,iOS app 是单进程的,并没有多进程并发的需求,这和 SQLite 的设计初衷是不相同的。这就给我们的优化提供了理论上的基础。在 iOS 这一特定场景下,我们可以舍弃兼容性,提高并发性。

新的方案修改为,当 OS 层进行 lock 操作时:

  1. 通过 pthread_mutex_lock 进行线程锁,防止其他线程介入。然后比较状态量,若当前状态不可跳转,则将当前期望跳转的状态,插入到一个 FIFO 的 Queue 尾部。最后,线程通过 pthread_cond_wait 进入 休眠状态,等待其他线程的唤醒。
  2. 忽略文件锁

当 OS 层的 unlock 操作结束后:
1. 取出 Queue 头部的状态量,并比较状态是否能够跳转。若能够跳转,则通过 pthread_cond_signal_thread_np 唤醒对应的线程重试。

新的方案可以在 DB 空闲时的第一时间,通知到其他正在等待的线程,最大程度地降低了空等待的时间,且准确无误。

此外,由于 Queue 的存在,当主线程被其他线程阻塞时,可以将主线程的操作“插队”到 Queue 的头部。当其他线程发起唤醒通知时,主线程可以有更高的优先级,从而降低用户可感知的卡顿

2. I/O 性能优化

上面介绍了多线程并发的优化,接下来将介绍 I/O 方面的优化。

2.1 mmap

提到 I/O 效率的提升,最容易想到的就是 mmap了,它可以减少数据从 kernel 层到 user 层的数据拷贝,从而提高效率。

SQLite 不仅支持 mmap,而且推荐使用,在大多数平台是在一定程度上默认打开的。然而早期的 iOS 版本的存在一些 bug,SQLite 在编译层就关闭了在 iOS 上对 mmap 的支持,并且后知后觉地在16年1月才重新打开。所以如果使用的 SQLite 版本较低,还需注释掉相关代码后,重新编译生成后,才可以享受上 mmap 的性能。

下图就是 SQLite 注释掉相关代码的 commit

开启 mmap 后,SQLite 性能将有所提升,但这还不够。因为它只会对 DB 文件进行了 mmap,而 WAL 文件享受不到这个优化。原因如下:

开启 WAL 模式后,写入的数据会先 append 到 WAL 文件的末尾。待文件增长到一定长度后,SQLite 会进行 checkpoint。这个长度默认为1000个页大小,在 iOS 上约为3.9MB。

而在多句柄下,对 WAL 文件的操作是并行的。一旦某个句柄将 WAL 文件缩短了,而没有一个通知机制让其他句柄进行更新 mmap 的内容。此时其他句柄若使用 mmap 操作已被缩短的内容,就会造成 crash。而普通的 I/O 接口,则只会返回错误,不会造成 crash。因此,SQLite 没有实现对 WAL 文件的 mmap。

显然 SQLite 的设计是针对容量较小的设备,尤其是在十几年前的那个年代,这样的设备并不在少数。而随着硬盘价格日益降低,对于像 iPhone 这样的设备,几 MB 的空间已经不再是需要斤斤计较的了。

另一方面,文件重新增长,对于文件系统来说,这就意味着需要消耗时间重新寻找合适的文件块。

权衡两者,我们可以改为

  1. 数据库关闭并 checkpoint 成功时,不再 truncate 或删除 WAL 文件,只修改 WAL 的文件头的 Magic Number。下次数据库打开时, SQLite 会识别到 WAL 文件不可用,重新从头开始写入。
  2. 为 WAL 添加 mmap 的支持 有了上面两个优化,整体性能就会提升不少了。

这里我没有贴具体代码需要改哪些地方,一方面是因为改动点较零散,另一方面是代码上的改动并不难。这个优化的工作量主要是在 SQLite 原理和优化点的挖掘上了,大家可以根据优化方案去尝试。

3. 其他优化

不过我们还有一些简单易行且效果还不错的小优化,希望可以成为大家打开 SQLite 黑盒的一个契机。

3.1 禁用文件锁

如我们在多线程优化时所说,对于 iOS app 并没有多进程的需求。因此我们可以直接注释掉 os_unix.c 中所有文件锁相关的操作。也许你会很奇怪,虽然没有文件锁的需求,但这个操作耗时也很短,是否有必要特意优化呢?其实并不全然。耗时多少是比出来。

SQLite 中有 cache 机制。被加载进内存的 page,使用完毕后不会立刻释放。而是在一定范围内通过 LRU 的算法更新 page cache。这就意味着,如果 cache 设置得当,大部分读操作不会读取新的 page。然而因为文件锁的存在,本来只需在内存层面进行的读操作,不得不进行至少一次 I/O 操作。而我们知道,I/O 操作是远远慢于内存操作的。

3.2 禁用内存统计锁

SQLite 会对申请的内存进行统计,而这些统计的数据都是放到同一个全局变量里进行计算的。这就意味着统计前后,都是需要加线程锁,防止出现多线程问题的。

以下 SQLite 内存申请的函数可以看到,当内存统计打开时,会跑代码的第二个 if,malloc 的前后被锁保护了起来。

其实这里内存申请的量不大,并不是非常耗时的操作,但却很频繁。多线程并发时,各线程很容易互相阻塞。因为耗时很短,所以被阻塞的时间也很短暂。似乎不会有太大问题。但频繁地阻塞却意味着线程不断地切换,这是个很影响性能的操作,尤其对于单核设备。

因此,如果不需要内存统计的特性,可以通过 sqlite3_config(SQLITE_CONFIG_MEMSTATUS, 0)进行关闭。这个修改虽然不需要改动源码,但如果不查看源码,恐怕是比较难发现的。

4. 结语

总的来说,移动客户端数据库虽然不如后台数据库那么复杂,但也存在着不少可挖掘的技术点。

这次也只尝试了对 SQLite 原有的方案进行优化,而市面上还有许多优秀的数据库,如 LevelDB、RocksDB、Realm 等,它们采用了和 SQLite 不同的实现原理。后续我们将借鉴它们的优化经验,尝试更深入的优化。

以上就是我今天的分享,谢谢大家。

问答环节

Q1 :前一阵微信提示我微信数据文件发现有损坏,这个是什么原因呢?

这个是数据库损坏,SQLite 是以B树结构存储的,如果某一个节点发生损坏,可能导致无法读取数据。损坏的原因多种多样,如断电、文件系统错误、硬盘损坏等。据我所知很多产品都出现了类似问题。

你看到的那个是微信的损坏监测和修复逻辑,我们做了自研的工具进行修复。这块我们后续也会分享 db 损坏的监测、保护、修复方案的

Q2 :请问 sqlite 有时候会出 signal 11的错误,可能是什么原因导致的

signal 11 就是 SQLITE_CORRUPT,上面提到的数据库损坏的其中一种。另一种是26 SQLITE_NOTADB

Q3 :请问微信在全文索引上有实践吗?有没有自己做本地的搜索索引

SQLite 是支持有全文索引的支持的,我们要做的是提供一个好的,支持中文的分词器。

Q4 :请问微信在 db 文件修复上有什么心得呢?

看来大家对 db 文件损坏很关注啊。SQLite 提供了 PRAGMA integrity_check 的工具检测损坏 和 DUMP 工具导出损坏 db。但从实践来看,效果并不理想。我们采用了按 BTree 结构遍历修复的方式,以后有机会可以分享给大家

Q5 :目前有没有已有的优化过的 sqlite 框架可供使用呢?

iOS上SQLite 的框架似乎只有 FMDB 和 CoreData,坦白说两个都不是很好。我们是自己封装的 WCDB 框架。

Q6 :微信的 orm 是怎么搞的

通过封装和规范来处理 ORM

Q7 :请问下多句柄怎么开启,是修改 sqlite 源码后再编译的吗?

这个最开始有提到了
1. 开启句柄多线程支持的配置 PRAGMA SQLITE_THREADSAFE=2
2. 确保同一个句柄同一时间只有一个线程在操作

Q8 :微信是怎么分析它的锁竞争的?

最重要的是读懂源码。辅助手段可以有 SQLite 官方的 Technical/Design Document 和 Instrument 工具

Q9 :请问有没有对能耗的监测和优化经验?

检测相关的我们有卡顿监控系统,可以到我们的公众号 WeMobileDev 上了解

Q10 :请问 sqlite 优化后有性能对比数据吗,差别有多大?

性能数据我以我们的卡顿系统为准,多线程并发优化使得卡顿率从4.08%降至0.19,I/O 优化使得读卡顿从1.50%降至0.20%,写卡顿从1.18%降至0.21%

Q11 :iOS 客户端用操作数据库需要每次先 open,执行完了再 close,每次都这样,还是 app 只需要开关一次比较好呢?

常用的 db 没有必要经常开关,db 占用的内存并不高,可以权衡一下

Q12 :微信对于本地空间不足会有一个强提醒,这是出于什么考虑?不同机型有不同的策略吗?

空间不足是个硬伤,所谓巧妇难为无米之炊。如16GB 的 iPhone,其实很影响正常使用了。不同机型会做细化

Q13 :请问 sqlite 多线程机制,大概能应付多大量级的数据库操作(基本无卡顿),微信有这方面的测试体验吗,然后是使用了底层代码修改多线程机制后,有大概的提升量级吗?

优化的效果我们是以卡顿系统检测到的为准的。能否减少用户感知到的卡顿,优化用户体验才是重点,而不在于能承受多大的量级

Q14 :微信对于数据库升级有没有特别优化的地方?或者说不同版本的跳版本升级

不知道这个问题指的是 SQLite 的升级还是表结构的升级。前者的话,暂时没看到 SQLite 新版本有比较大的特性值得我们跟进。后者可以用 alter table 在封装层支持升级,性能损耗不大

Q15 :请问微信的 SQLite 有没有开启加密?如果有,性能是否有提升空间?

iOS 版本目前没有开启加密

Q16 :微信 sqllite 数据库用的内存数据库吗?那和文件数据库导入导出怎么控制的?

没有使用内存数据库

Q17 :可以问一下,目前做 iOS 版,没有针对 android 版么?

这次分享的大部分内容,对Android也是通用的,触类旁通即可。

Q18 :请问下,句柄开几个比较合适?读写分离开来对性能是否会有提升呢?

我们是按需生成新句柄的,并设了上限,若超过上限会有报警。如果同一时间并发量太大的话,其实更多要考虑业务层是否适用得当。至于业务层的使用,若能做细化那自然是更好

更多精彩内容欢迎关注bugly的微信公众账号:

腾讯 Bugly是一款专为移动开发者打造的质量监控工具,帮助开发者快速,便捷的定位线上应用崩溃的情况以及解决方案。智能合并功能帮助开发同学把每天上报的数千条 Crash 根据根因合并分类,每日日报会列出影响用户数最多的崩溃,精准定位功能帮助开发同学定位到出问题的代码行,实时上报可以在发布后快速的了解应用的质量情况,适配最新的 iOS, Android 官方操作系统,鹅厂的工程师都在使用,快来加入我们吧!

【腾讯Bugly干货分享】微信iOS SQLite源码优化实践 本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57b58022433221be01499480 作者:张三华 前言随着微信iOS客户端业务的增长,在数据库上遇到的性能瓶颈也逐渐凸显。在微信的卡顿监控系统上,数据库相关的卡顿不断上升。而在用户侧也逐渐能感知到这种卡顿,尤其是有大量群聊、联系人和消息收发的重度用户。我们在对SQL 阅读详情

相关推荐

物理专业书库模板(1):物理学书单(适合物理专业本科生、研究生、科研工作者、物理爱好者...)

物理专业书库模板(1):物理学书单(适合物理专业本科生、研究生、科研工作者、物理爱好者...) 求赞求喜欢求分享,建议关注,防止文章丢失。

hepyang的博客 2179

Android使用SQLITE3 WAL模式

在sqlite3.7版本之后就支持write ahead logging(WAL)模式,开启WAL模式可以提高写入数据库的速度,读和写之间不会阻塞,但是写与写之间依然是阻塞的,但是如果使用默认的TRUNCATE模式,当写入数据时会阻塞android中其他线程或者进程的读操作,并发降低。 相反,使用WAL可以提高并发。 由于使用WAL比ROLLBACK JOURNAL的模式减少了写的I/O,所以写入

努力才有可能得到! 1万+

S32K314 EB配置MCAL全模块讲解【Autosar——1 MCU模块详解】持续更新中

FIRC(fast internal RC Oscillator) :高速内部时钟,固定48MHZ;SIRC(Slow Internal RC Oscillator):低速内部时钟,固定32KHZ;FXOSC(Fast Crystal Oscillator Digital Controller):高速外部晶振(8-40MHZ),根据原理图选型进行配置;SXOSC():外部低速外部时钟,固定输入32.768KHZ;PLL_PHIn_CLK:时钟倍频锁相环时钟范围(640-1280MHZ);

qq_40488886的博客 1779

SQLite内部机制和新特性

SQLite内部机制和新特性 一、B-tree和Pager模块 B-tree为SQLite VDBE提供了O(logN)级时间复杂度的插入和查询,通过双向遍历记录实现O(1)级时间复杂度的删除。B-tree是自平衡的,能够对碎片清理和内存再分配进行自动管理。B-tree对如何读写磁盘没有限定,只是关注页之间的关系。 B-tree在需要一个页或修改一个页的时候会通知Pager。修改页时,如果使用传统的回滚日志,pager首先将原始页复制到日志文件,同样,pager在B-tree完成操作时收到通知,并基于所处的

qq_34934140的博客 1184

zabbix 监控EMC存储

经过搜索,找到了脚本地址,该项目应该是模板原作者创建的,该项目也有zabbix模板,和上面的应该是相同的,我用的是上面的模板。./unity_get_state.py --api_ip='X.X.X.X' --api_port='443' --api_user='zabbix' --api_password='PASSWORD' --storage_name="zabbix web前端配置的主机名" --discovery。修改权限,给zabbix用户执行权限,模板调用时以zabbix用户执行。

wangyfde的专栏 3754

NDVI空间分布变化Slope趋势分析与F检验(自用)

1.NDVI数据预处理2.一元线性回归分析3.Slope趋势分析与F检验

什么都学亿点点的博客 9017

腾讯开源微信数据库框架WCDB

腾讯开源微信数据库框架WCDBWCDB(WeChat Database)是一个高效、完整、易用的移动数据库框架,基于SQLCipher,支持iOS, macOS和Android。最早期的微信,各个平台除了“使用 SQLite”这个共识,基本各自为政。Android 平台由于 SDK 提供的支持尚可,而且使用 NDK 开发不便,自然选择系统 API 接口进行开发。iOS 情况则有不同。系统提供的Co...

haifangnihao的博客 4893

LLC谐振变换器软启动,不只是“慢启动”,还是“智能启动”

LLC谐振变换器的软启动,不只是“慢慢来”,而是要在控制时序、限流、响应速度之间精妙权衡。而数字控制,特别是用查表法或混合信号法,为实现真正的“最佳轨迹”提供了可能。✨小Tips:如果你的系统成本敏感,选择查表法准没错;如果你的设计目标是超高速响应,那就上混合信号的高配方案!

weixin_43199439的博客 691

WeChatExporter终极指南:三步破解iOS微信数据备份的技术迷思

你是否曾因误删重要微信聊天记录而懊恼不已?是否担心更换手机后那些珍贵对话会永远消失?在数字时代,我们的聊天记录不仅是沟通工具,更是承载着情感记忆和工作痕迹的数字资产。WeChatExporter正是为解决这一痛点而生的开源工具,它能帮你将iOS微信聊天记录完整导出并永久保存,让你真正拥有自己的数据主权。 ## 问题场景:为什么你的微信数据被困在"数字孤岛"? 微信作为中国最大的即时通讯工具,每

gitblog_00548的博客 434

FPGA 学习笔记:Vivado 2020.2 MicroBlaze MIG 测试 DDR3 篇四

FPGA 学习笔记:Vivado 2020.2 MicroBlaze MIG 测试 DDR3 篇四

坚韧与专注 2160

一般无穷积分的收敛判别法

文章目录积分里的狄屎判别法证明阿贝尔判别法总结补充:级数中的狄屎和Abel 积分里的狄屎判别法 F(u)=∫auf(x)dx在[a,+∞)F(u)=\int_a^uf(x)dx在[a,+\infty)F(u)=∫au​f(x)dx在[a,+∞)有界 x→+∞时,g(x)单减→0x\to+\infty时,g(x)单减\rightarrow0x→+∞时,g(x)单减→0 ⇒\Rightarrow⇒ ...

universe_1207的博客 1万+

【腾讯Bugly干货分享】微信 iOS SQLite 源码优化实践

本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57b58... 作者:张三华 前言 随着微信iOS客户端业务的增长,在数据库上遇到的性能瓶颈也逐渐凸显。在微信的卡顿监控系统上,数据库相关的卡顿不断上升。而在用户侧也逐渐能感知到这种卡顿,尤其是有大量群聊、联系人和消息收...

weixin_33812433的博客 227

【30】软考软件设计师——UML类图与用例图满分精讲|下午第3题常考核心

本文是《软件设计师·50讲通关|从零基础到工程师职称》专栏第30篇,聚焦**模块四:应用技术(下午题)第3道高频大题**,UML建模是历年下午必考核心,单题分值稳定10~12分。全文深度拆解两大核心UML图表:**类图**与**用例图**,超详细讲解类图三层结构、可见性修饰符、五大核心关系(泛化/关联/依赖/聚合/组合)的判定标准与绘图规范;吃透用例图参与者、系统边界、三大关系(包含/扩展/泛化)的底层逻辑,搭配独家**关系秒杀口诀、标准绘图模板、真题改错技巧**;全文适配补图、判断关系、分析场景、纠错优化

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 572

WeChatExporter技术架构深度解析:iOS微信数据提取与可视化方案

在移动应用数据管理领域,微信聊天记录的本地化备份与解析一直是技术实现中的难点。WeChatExporter作为一款开源工具,通过逆向工程iOS微信数据存储机制,实现了聊天记录的完整提取与可视化展示。本文将深入剖析该工具的技术架构、实现原理及应用场景,为开发者提供一套完整的微信数据解析技术方案。 ## 数据提取机制与SQLite逆向分析 微信iOS版本采用SQLite数据库作为核心数据存储方案,

gitblog_00505的博客 435

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

【个人开发】通过SQLite获取微信聊天记录

之前都知道微信聊天记录备份的数据在本地的db文件里,但是一直访问不了db文件,今天拜读了简书上大佬的文章,有点醍醐灌顶,原因是db文件的访问需要密钥。再一次尝试,竟然成了。先上效果:数据成功读取,后面python啥的,都好处理了。

weixin_44505713的博客 1万+

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

wa-sqlite开源项目手册

wa-sqlite项目基于WebAssembly技术,使得SQLite数据库能在浏览器环境中运行。以下是项目的典型目录结构及其简要说明: ``` rhashimoto/wa-sqlite/ ├── ACKNOWLEDGMENTS.md # 致谢文件,记录贡献者和支持者的信息。 ├── LICENSE # 许可证文件,采用MIT许可协议。 ├── Makefile ...

gitblog_00808的博客 451

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

微信聊天记录分析

(解释一下为啥选平板没选手机,原因是手机备份需要太久了,东西贼多,而平板相比于手机容量小很多,微信聊天记录占据也不是很大,这就可以大大提高了我备份的速率,当然前提需要在把手机上的关于Ta的全部聊天记录先迁移到平板上去,否则这不是分析了个寂寞嘛。后面就是对csv进行各种分析了,我这里采用的是Python,具体的代码后续待我整理完,我打算挂到GitHub上面,供大家借鉴。打开该软件,列表里会自动出现备份,我们选择微信聊天记录,然后直接将其导出就行,我导出了在。至此,我们已经完成了数据的导出!

lzmmath的博客 1407

sqlite:微信数据库

文章目录一、安装java1、下载安装文件2、配置环境变量3、安装成功测试二、本地备份数据库三、获取数据库密码四、从数据库中导出需要的数据1、导数据2、表格对应数据 一、安装java 1、下载安装文件 Java SE Development Kit 14.0.2 Downloads(最新) 2、配置环境变量 a、新建两个系统环境变量 变量名: CLASSPATH 变量值:.;tools.jar;dt.jar; 变量名: JAVA_HOME 变量值:你的Java安装路径 b、新增环境变量 变量名: Pat

weixin_44374471的博客 3348

iOS 微信数据库分析

原文地址:http://www.jianshu.com/p/07a8d87e698b 1. 怎么得到这些文件? 过去,我可以提示用户在越狱之后用 iTools 自行把微信 App 所在文件夹复制出来。然而自从某个版本的 iOS 开始,在不越狱的情况下,我们只能看到 /User/Media 这里的文件,而需要的本地数据在 /User/Containers/Data/Application

qq471656957的专栏 7917

Sqlite优化v2

如果我们在项目中有使用 SQLite,那么下面这个SQLiteDatabaseLockedException就是经常会出现的一个问题。 归根到底是因为并发导致,而 SQLite 的并发有两个维度,一个是多进程并发,一个是多线程并发。下面我们分别来讲一下它们的关键点。多进程并发SQLite 默认是支持多进程并发操作的,它通过文件锁来控制多进程的并发。SQLite 锁的粒度并没有非常细,它针对的是整个 DB 文件。 简单来说,多进程可以同时获取 SHARED 锁来读取数据,但是只有一个进程可以获取 EXCL

麦峰强的博客 1476

微信iOS SQLite源码优化实践

# 微信iOS SQLite源码优化实践 Dev Club 是一个交流移动开发技术,结交朋友,扩展人脉的社群,成员都是经过审核的移动开发工程师。每周都会举行嘉宾分享,话题讨论等活动。 本期,我们邀请了腾讯WXG iOS 开发工程师——张三华,为大家分享《微信iOS SQLite源码优化实践》。 ### 分享内容简介: SQLite是微信iOS选用的数据库,随着微信iOS客户端业务的增长...

Philm_iOS的博客 858

微信移动端数据库组件WCDB系列(一)-iOS基础篇

前言 WCDB(WeChat DataBase)是微信官方的移动端数据库组件,致力于提供一个高效、易用、完整的移动端存储方案。 它包含三个模块: WCDB-iOS/Mac WCDB-Android 数据库损坏修复工具WCDBRepair 目前正在筹备开源中。 背景 对于iOS开发者来说,数据库的技术选型一直是个令人头痛

ihoudf 5197

微信为什么使用 SQLite 保存聊天记录?

它不支持的功能在其他一些主要产品中也同样不支持(在聚合中语句中的distinct,width_bucket, respect|ignore nulls和from first|last等语句)。SQLite 从版本3.25.0开始,在使用over子句的聚合函数中支持了filter子句,但是在使用group by子句的聚合函数中还不支持。事实上,SQLite 是一个非常可靠的数据库,它可以处理 TB 级的数据,但它没有网络层。这是一个特有的SQL扩展,即它不是标准SQL的一部分,因此在下面的矩阵中是灰色的。

Rocky006的博客 2万+
上一篇: 【腾讯Bugly干货分享】基于RxJava的一种MVP实现
下一篇: 【腾讯优测干货分享】安卓专项测试之GPU测试探索
腾讯Bugly
博客等级 码龄12年 1875粉丝 201原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值