Recently in 软件开发 Category
stringstream a,b;
b << "hello";
a << b;
cout << a;
猜猜输出是什么?不是“hello”!这一句 a << b 后变量a拿到的不是变量b的内容,而是b的地址!正确的做法应该是 a << b.str(),这样a才是"hello"。
stringstream自己的<<方法居然没有重载变量为stringstream类型的情况,真是奇怪。
b << "hello";
a << b;
cout << a;
猜猜输出是什么?不是“hello”!这一句 a << b 后变量a拿到的不是变量b的内容,而是b的地址!正确的做法应该是 a << b.str(),这样a才是"hello"。
stringstream自己的<<方法居然没有重载变量为stringstream类型的情况,真是奇怪。
php可以通过dba_open系列函数直接操作4.x版本的berkeleydb数据文件。昨天发现在dba_insert的时候php报出了
Segmentation fault
的错误,当时bdb文件已经3G多了。先怀疑是bdb有大小限制,可我们用的是64位系统啊。于是改用c来操作bdb,写了11G的bdb文件都没有问题,最后才确认:装的php是32位下编译的php,它能顺利的在64位系统下直接运行,但写库就不能太大了,理论上来说不能超过4G,至于为什么3G就不行了,可能bdb的寻址有特殊要求吧。
解决这个问题也很简单,按key哈希开,分成16个bdb来存数据,这样单个文件就不会超过3G了。
gprof是个性能分析工具。今天用它分析程序,程序叫Mig(化名),加了“-pg”参数编译链接后运行,出不来Mig.gmon文件,先怀疑是权限问题,看了看权限是对的,同事帮忙一看,唉,可执行文件是个软链接,真正的Mig.gmon被写到被链接的真是可执行文件所在的目录去了。
搞了一阵,发现又找不到Mig.gmon,真是多灾多难,这次又是什么原因?既不是权限又不是软链接,是Mig程序里有一段调用了system函数,里面用“cd”切换了工作目录,而Mig.gmon是应该写在“当前目录”下的,所以又找不着了。
现在才明白为什么很多shell命令都要求写出输出的具体文件名,就是为了避免把输出写到易变的“当前目录”里。
搞了一阵,发现又找不到Mig.gmon,真是多灾多难,这次又是什么原因?既不是权限又不是软链接,是Mig程序里有一段调用了system函数,里面用“cd”切换了工作目录,而Mig.gmon是应该写在“当前目录”下的,所以又找不着了。
现在才明白为什么很多shell命令都要求写出输出的具体文件名,就是为了避免把输出写到易变的“当前目录”里。
BerkeleyDB的cache可以采用Hash和BTree两种索引方式,今天测试了这两种方式的存取速度,测试方法是:向bdb中写100万条记录,key是1至100万的数字编号,value分别是32、64、128、256字节的字符串,然后再顺序查询这100万条记录,分别统计写和读的时间,其中bdb版本为4.2。
当cache开到1G大小时,数据如下(其中大小单位为字节,时间单位为秒):
由于cache非常大,几乎所有的数据都可以放在里面,所以两种索引方式的存取效率基本一样。
如果把cache改为32M,测试结果又如下:
其中“缺”字表示测试无法进行,因为当数据太大时,用Hash索引运行bdb几乎把机器搞死,我不得不中断测试。这组测试看得出:如果使用BTree,随着数据的翻倍,写的时间也近乎翻倍,但读的时间非常稳定,对于数据量大、写少读多的应用(比如bbs、图片服务等)应该尽量使用BTree索引。
总的来看,BerkeleyDB的Hash索引表现古怪,只在小cache小数据量的情况下查询速度快于BTree,可现在哪会有这种情况?还是用BTree索引保险一些。
当cache开到1G大小时,数据如下(其中大小单位为字节,时间单位为秒):
| Cache为1G时 | ||||
| value大小(字节) | Hash写时间 | Hash读时间 | BTree写时间 | BTree读时间 |
| 32 | 12 | 6 | 4 | 3 |
| 64 | 8 | 4 | 4 | 3 |
| 128 | 7 | 4 | 5 | 3 |
| 256 | 7 | 4 | 6 | 3 |
由于cache非常大,几乎所有的数据都可以放在里面,所以两种索引方式的存取效率基本一样。
如果把cache改为32M,测试结果又如下:
| Cache为32M时 | ||||
| value大小(字节) | Hash写时间 | Hash读时间 | BTree写时间 | BTree读时间 |
| 32 | 11 | 6 | 5 | 39 |
| 64 | 205 | 62 | 17 | 50 |
| 128 | 缺 | 缺 | 44 | 42 |
| 256 | 缺 | 缺 | 186 | 51 |
其中“缺”字表示测试无法进行,因为当数据太大时,用Hash索引运行bdb几乎把机器搞死,我不得不中断测试。这组测试看得出:如果使用BTree,随着数据的翻倍,写的时间也近乎翻倍,但读的时间非常稳定,对于数据量大、写少读多的应用(比如bbs、图片服务等)应该尽量使用BTree索引。
总的来看,BerkeleyDB的Hash索引表现古怪,只在小cache小数据量的情况下查询速度快于BTree,可现在哪会有这种情况?还是用BTree索引保险一些。
今天才第一次使用gdbm,发现在往里面放数据时,进程的内存几乎没有变化,而在取数据时,内存才慢慢变大。虽然数据文件有整整180MB,但遍历完数据后内存也才35MB。看来gdbm是直接把数据写往硬盘了,取的时候又用了一个缓存。
虽然gdbm和mdbm用的都是Per-Ake Larson的动态哈希算法,但mdbm是在共享内存里hash,而gdbm直接hash到硬盘上了,且缓存也不是共享的。这造成gdbm比mdbm读写慢很多,而且如果启动多个进程,gdbm会白白浪费内存空间。
在内存充足的情况下,当然选用mdbm,即使内存不足,也可以选用BerkeleyDB,因为bdb的缓存大小可调而且是共享的。那gdbm用在哪里呢?只能用在需要存取少量数据而对存取性能要求又很低的场合了,有这种场合吗?做为老牌存取库dbm的GNU版本,gdbm面对的是过去内存紧缺的老unix系统,而且那时候共享内存机制还不成熟,所以它就用了一个现在看来如此“弱”的存储策略。
如今大内存的机器比比皆是,在服务器领域dbm估计就此退出舞台了。
虽然gdbm和mdbm用的都是Per-Ake Larson的动态哈希算法,但mdbm是在共享内存里hash,而gdbm直接hash到硬盘上了,且缓存也不是共享的。这造成gdbm比mdbm读写慢很多,而且如果启动多个进程,gdbm会白白浪费内存空间。
在内存充足的情况下,当然选用mdbm,即使内存不足,也可以选用BerkeleyDB,因为bdb的缓存大小可调而且是共享的。那gdbm用在哪里呢?只能用在需要存取少量数据而对存取性能要求又很低的场合了,有这种场合吗?做为老牌存取库dbm的GNU版本,gdbm面对的是过去内存紧缺的老unix系统,而且那时候共享内存机制还不成熟,所以它就用了一个现在看来如此“弱”的存储策略。
如今大内存的机器比比皆是,在服务器领域dbm估计就此退出舞台了。