Sunpinyin加速脚本 – 内存缓存词库
一 11
System Fcitx, sunpinyin, Ubuntu 24 Comments
UPDATE2:感谢“据说要有”的建议,已修改脚本。
UPDATE1:脚本在异常退出(比如收到KILL信号,系统断电等)后再次运行时会有严重的BUG,导致用户词库丢失。现已修正,强烈推荐各位使用者更新。如果已经有过异常退出的用户,请退出脚本后至~/.sunpinyin/目录下检查(ls -l),若userdict为符号链接,请删除之,sunpinyin将重建新的用户词库。对因此造成的数据损失表示抱歉。
之前在一篇文章里,我提到了在Ubuntu下使用fcitx + sunpinyin配合hubertstar的大词库实现媲美搜狗的流畅输入,但是仍然有一个大问题——当词库过大的时候输入中会出现停顿现象,严重影响用户体验(因此我当时也只推荐使用small版词库)。
这是因为fcitx和sunpinyin的词库都是使用SQLITE,在输入时需要反复查询,由于词库的特殊性(前后两个查询的词经常离得很远),SQLITE的缓存机制很难起效,因而只能反复读硬盘,导致速度很慢。
不过,在大宝的启发下,我参考了Ubuntu中文论坛里hubertstar的帖子,以及大宝的博客,我写了一个供Ubuntu使用的sunpinyin加速脚本,效果非常不错,拿上来和大家分享。
原理非常暴力——直接将整个sunpinyin的userdict放入/dev/shm(即存在于内存中的tmpfs),然后符号链接回来,相当于手动暴力cache整个词库,大幅提高了速度。这样做法的缺点就是内存消耗较大——我现在使用的大词库有100+MB,即需要100+MB的内存,不过,当下基本每个人都有2G+的内存,本来也就很难用完,这样正好提高了内存的利用率。
使用方式:将这个脚本放在方便的地方,通过chmod +x赋予可执行权利,在“系统 -> 首选项 -> 启动应用程序”中添加这个脚本。
相比于hubertstar和大宝的脚本,这个脚本有如下优点:
- 使用方便,只需要在GNOME会话登陆后自动运行即可;
- 自动将用户词库变更备份回原目录,不会导致自造词丢失;
- 卸载方便,脚本在退出时(包括关机或登出)会自动恢复用户词库,因而如果没有启动这个脚本也不影响运行sunpinyin;
- 完全运行在用户空间,不需要使用服务或者cron。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | #!/bin/bash #sunpinyin_speed_up.sh # Sunpinyin Speed Up Script for Ubuntu (by memory caching, and no data loss) # You can run this script in background on GNOME logging in. # Originally written Hubert Star, modified by Bob Robot (http://robotshell.org/). # Capture the exit signal, make sure it is the FIRST uncommented line. trap "do_exit" SIGHUP SIGINT SIGQUIT SIGTERM SUN_DIR="${HOME}/.sunpinyin" SHM_USERDICT="/dev/shm/sunpinyin_userdict.sh0" # Backup the userdict and restore all changes made by this script on exit. do_exit() { cp -f "${SHM_USERDICT}" "${SUN_DIR}/userdict.real" rm -f "${SHM_USERDICT}" mv -f "${SUN_DIR}/userdict.real" "${SUN_DIR}/userdict" exit 0 } # Work around for abnormal quit. if [ -e "${SUN_DIR}/userdict.real" ] then rm -f "${SHM_USERDICT}" mv -f "${SUN_DIR}/userdict.real" "${SUN_DIR}/userdict" fi # Rename the real userdict, copy it to RAM and make a symblic link back. # From now on the modification and query on userdict takes place in RAM. mv -f "${SUN_DIR}/userdict" "${SUN_DIR}/userdict.real" cp -f "${SUN_DIR}/userdict.real" "${SHM_USERDICT}" ln -sf "${SHM_USERDICT}" "${SUN_DIR}/userdict" # Automatically backup the userdict, make sure not losing the modification. p_count=0 while [ true ] do p_count=$(($p_count+1)) sleep 1800 if [ $p_count == 4 ] then p_count=0 cp -f "${SHM_USERDICT}" "${SUN_DIR}/userdict.real" fi p_size_shm=$(ls -l "${SHM_USERDICT}" | awk '{print $5}') p_size_real_t=$(ls -l "${SUN_DIR}/userdict.real" | awk '{print $5}') p_size_real=$(($p_size_real_t+512)) if [ $p_size_shm -ge $p_size_real ] then cp -f "${SHM_USERDICT}" "${SUN_DIR}/userdict.real" fi done |
经测试,不论多大的词库(只要你内存无压力)都可以顺畅输入。赶紧把你的sunpinyin词库换成超大词库,来体验更流畅的Ubuntu拼音输入吧~
Related posts:
RSS
Twitter
Fanfou
Email


二 03, 2012 @ 20:16:39
如果我想在 Fcitx-Googlepinyin 上实现这个效果,该怎么做?
十一 22, 2011 @ 01:39:53
不知道為什麼用了脚本以后还是很卡。。系统10.10,内存8g。。top看内存也很充足。。。
十一 26, 2011 @ 20:30:18
看看有木有
/dev/shm/sunpinyin_userdict.sh0
十一 29, 2011 @ 13:06:02
有的。。
l@l-Aspire-4750:/dev/shm$ ll
总用量 178004
drwxrwxrwt 2 root root 280 2011-11-29 13:04 ./
drwxr-xr-x 19 root root 3800 2011-11-29 12:54 ../
-r——– 1 l l 67108904 2011-11-29 13:04 pulse-shm-1526596234
-r——– 1 l l 67108904 2011-11-29 12:54 pulse-shm-1537590344
-r——– 1 l l 67108904 2011-11-29 13:04 pulse-shm-1848057040
-r——– 1 l l 67108904 2011-11-29 13:00 pulse-shm-2233740194
-r——– 1 gdm gdm 67108904 2011-11-29 12:50 pulse-shm-2688015300
-r——– 1 l l 67108904 2011-11-29 12:54 pulse-shm-3224336355
-r——– 1 l l 67108904 2011-11-29 12:56 pulse-shm-3371147112
-r——– 1 l l 67108904 2011-11-29 12:51 pulse-shm-3927039547
-r——– 1 l l 67108904 2011-11-29 12:51 pulse-shm-4129499632
-r——– 1 l l 67108904 2011-11-29 12:51 pulse-shm-583031479
-r——– 1 l l 67108904 2011-11-29 12:54 pulse-shm-677051927
-rw-r–r– 1 l l 181406720 2011-11-29 12:55 sunpinyin_userdict.sh0
而且很奇怪,我把脚本加到启动应用程序中就不行,但是我在终端里手动执行脚本就可以。。。
十一 19, 2011 @ 00:32:25
能打包么?
ppa源啥的- -
八 03, 2011 @ 05:06:35
效果很好啊,不知道强制断电会不会有影响?
八 08, 2011 @ 12:36:09
会有影响。。。
六 19, 2011 @ 00:04:51
非常棒的方法,之前曾经引用到我的博客中忘了跟博主打招呼了不好意思
今天刚好重做了系统尝试了这个方法确实更有优势,还发现脚本内容有更新~一并同步了:-))
四 27, 2011 @ 21:44:56
是不是可以加一句continue。否则,如果这段时间词典大小增量大于512的话,就会复制两次了。
if [ $p_count == 4 ]
then
p_count=0
cp -f “${SHM_USERDICT}” “${SUN_DIR}/userdict.real”
continue
fi
四 29, 2011 @ 22:36:45
不会的,第一个if如果执行了的话磁盘上的词典就和内存里的一样了,不可能内存里的在那一瞬间大了512。
四 29, 2011 @ 23:47:48
但是p_size_real的值是反映两个if之前的userdict.real的大小。(当然p_size_shm也是之前SHM_USERDICT的大小)
然后开始判断。
在第一个if执行后,第二个if判断时这个值并没有更新成新userdict.real的值吧
五 01, 2011 @ 12:21:28
Oh! 是我疏忽了~!谢谢你!
四 05, 2011 @ 08:51:31
还有个问题是,我发现不管在终端里面 用ctrl+c还是ctrl+\ 终断这个脚本,并且kill了sunpinyin的进程,把ramdisk也推出了,但是再打开sunpinyin后,我感觉词库实际上还是在ram里面,速度很快。但很容易造成词库的丢失。。。。。损失太大了。这是怎么回事儿?
四 08, 2011 @ 23:15:43
这是不应该发生的啊,你可以看看我的脚本,里面在捕捉到终止信号时会把词库备份回去并从shm里删掉,这样一来就变得完全和原来一样了,甚至连sunpinyin都不需要退出。但是你说的这个情况我似乎也有察觉到,有时候我结束了那个脚本但是检索词库还是很快,应该还是在内存里没错。这似乎和sunpinyin内部的机制有关系。但这时候会不会导致新的自造词丢失我就不知道了,没有尝试过,不过肯定不会导致整个词库丢失。
至于休眠的问题,好吧我错了(我的本本没有办法正常休眠,所以一直当作这个功能不存在 T T)。我找个能正常休眠的电脑试试看。按理说休眠是把所有内存上的东西弄到swap上,应该不会导致词库丢失的,除非shm是另外处理的。我去查查。
四 05, 2011 @ 08:34:04
lz如果有休眠的情况,还是不能保证词库不丢失啊。。。。在笔记本上,我都丢了好多次了。
三 22, 2011 @ 09:41:02
不知道是不是我的错觉,ln -sf “${SHM_USERDICT}” “${SUN_DIR}/userdict” 这句话我觉得有问题,做出来的是硬链接而不是软链接,所以仍然很卡;改成 ln -s -f 以后就正常了。
三 26, 2011 @ 16:03:49
ln -sf和ln -s -f是等价的,前一种写法更常见,是强制创建符号链接的意思。而且是不能把文件从SHM弄到其他地方的,这算是跨文件系统了。
三 03, 2011 @ 12:58:04
為什麼使用一段时间后非常卡,几乎不能用
三 06, 2011 @ 14:52:50
可能和系统对SHM的处理方式有关……你内存多大?
三 03, 2011 @ 11:18:04
不错,kde下面也可以正常使用。
二 25, 2011 @ 16:19:36
非常感谢啊!不过我发现注销后再登陆会重复执行脚本
二 25, 2011 @ 19:47:07
奇怪了,不应该啊……GNOME登出后gnome-session进程会结束,而登陆自启动程序应该是它的子进程,也会被结束才对啊……
二 25, 2011 @ 23:06:12
跟系统有关系?我装的10.10,反复试过N次了,每次登出再登入就会多一个进程。
一 11, 2011 @ 12:23:35
强烈支持阿。