在linux下一个有趣的STL文件IO问题

在linux下读一个巨大的日志文件, 2.4G

用正文文件的方式打开, 一行一行的读

char achbuf[ 4096 ] ;

ifstream ifile( "/cygdrive/h/logs/zz/ex051117.log" ) ;

if ( !ifile ) {

cout << "error in opening" << endl ;
return -1 ;
}

int i ;

for( i = 0 ; !ifile.eof() ; i++ )
{
ifile.getline( achbuf , sizeof( achbuf ) - 1 ) ;
}
这个过程用了51秒

2.4G的文件用51秒, 47M每秒, 已经接近硬盘的最高速度了.

当时想做个尝试, 看看用二进制方式打开一次读入16M能否会更快.

char achbuf[ 4096 * 4096 ] ;
ifstream ifile( "file.log" , ios::in | ios::binary ) ;

if ( !ifile ) {

cout << "error in opening" << endl ;
return -1 ;
}

int i ;

for( i = 0 ; !ifile.eof() ; i++ )
{
ifile.read( achbuf , sizeof( achbuf ) ) ;
}
这个过程竟然用了96秒!!!!!!!!!!
到论坛请教了一下, co给出一个链接: Fast read of binary files that alternate type
试了试co推荐的文章里说的方法, 加了 ifile.imbue( std::locale::classic());, 结果为88秒, 有提高.
改用下面的代码读是54秒, 和第一个速度相近了
FILE *pfile ;

pfile = fopen( "file.log" , "rbS" ) ;

if ( pfile == NULL ) {

cout << "error in opening" << endl ;
return -1 ;
}

int i ;

for( i = 0 ; !feof( pfile ) ; i++ )
{
fread( achbuf, 1 , sizeof( achbuf ) , pfile ) ; //16M
}

fclose( pfile ) ;
刚开始学习stl,不太清楚stl文件io实现的内部机制, 不清楚为什么二进制和正文文件的读入速度差这么多.
有知道的请不吝赐教. 有能答疑解惑者,赠烤鸭一只smile_tongue

又到中秋

现在是凌晨4点45, 坐在窗口旁, 俯瞰着整个小区。路灯静静得亮着,远方的工地偶尔传来一些机械的声音,旁边闷闷的电脑风扇声。又一个中秋开始了。

测试用Writely 来写blog ,感觉不错。在线Office 2007的测试帐号没申请到,只好先用用google。已经越来越喜欢上google的线上软件,微软做的能有这么好么?

update: Writely写的blog还是有些问题, 标题是空的,更新后又生成一个新的post. 看来还是要先用微软的Live writer

Google发布了新的搜索引擎

http://www.searchmash.com 悄无声息的发布了,有一些有趣的新特性。用户可以移动搜索结果,搜索文字会同时搜索图像,搜索结果中暂时没有Adwords广告。 mash是麦芽汁的意思,但google发布这个搜索引擎是什么意思却让人琢磨不透。难道是为了试验由用户主动参与来改进搜索结果? 还是以后google一些新的搜索技术会先在这个引擎尝试?

装了Ubuntu

版本6.06。 下面是浏览新浪网的截图:

效果不错, 就是中文字体不太好, 应该可以靠下载字体解决。安装过程非常简单,不比前几天安的Vista复杂. 随机安的软件里有OpenOffice, 浏览器Firefox, 还有Gaim Messenger, Evolution Email, Softphone, 多媒体播放器,居然还支持Remote Desktop, 绝对够用了. 据说Suse Linux的桌面比它的更酷,还没看过。2000年的Gnome就已经很漂亮, 但当时的配套桌面软件还不是那么成熟,现在感觉已经是完全可以和 Windows一角短长了。

将来Linux会不会在桌面市场替代Windows呢? 太古老的话题,可总是吸引人们讨论下去。 我现在用的软件有两个趋势, 一个是越来越多用Web的软件, 比如RSS Reader用Google Reader; Email 虽然还是用Outlook处理,但越来越多的用gmail; One note很少用了, 而是用google 的notebook, 家里记账原先用excel, 现在用google spreadsheet. 另一个趋势就是用开源的软件越来越多, 设计数据库用DB Designer, Text Editor用notepad++, 开发Linux下的C++程序用Eclipse, 记日记用Wordpress。 昨晚仔细看了看Vista, 说实话, 相当让我失望。 感觉并没有什么特别吸引人的特性。当初DOS到Windows 3.0, Windows3.1到Windows 95, Windows 95到98, 到2000都还是有特别吸引我的地方,让我迫不及待的升级。从2000到XP这个积极性就下降了很多, 到了Vista没带给我任何想升级的冲动。不知道是不是真的老了,还是Vista真的让人失望。

如果说Windows 和Linux是IT世界的两极,我好像越来越偏向Linux了。

一个太不成熟的WP插件

今天在Google Reader上看到有人推荐

Google Sitemaps – UTW Tag Addon for WordPress 2.0, 感觉想法不错, 应该对SEO有帮助, 按照那个网站上说的步骤装了一个。 结果看输出的sitemap.xml 居然里面的tag 链接都是指向这个插件作者的站点。 看了他的php源码, 居然把自己站点的链接写死在了代码里。 改成自己的试了试, 发现还是不行, 才注意到他在URL中没有考虑到亚洲字符。 自己也能改, 但不想浪费时间直接给卸载了。

大家有看到这个插件的就不要浪费时间了,这么不成熟的插件头一次见到, 白白浪费了10分钟。

未来应该会出现专门的数据存储冗灾服务提供商

最近看了很多关于存储的资料, 深raid, fc, sas, nas 一大堆名词扑面而来。 看的时候就一直在想一个问题, 如何能保证数据的安全性呢? 可以用raid, 可万一raid卡坏了怎么办? 那就用双机热备份, 可万一这个机房着火了怎么办, 那就只有在一个远离这个机房的地方再保存一个备份才能保证数据安全了。 大公司有这么做的, 北京政府甚至在昌平专门建有冗灾数据中心, 但这对广大的中小厂商来说有成本太高之嫌。这应该就是一个新的机会,IT业发展到现在需要有专业的第三方的廉价的数据存储冗灾公司。
下面设想一下这样的公司的实现细节,他应该有如下特点

  1. 这个公司有至少三个机房, 每个机房之间的直线距离, 至少超过1000公里, 其中至少有个机房, 和最远的机房有1万公里以上的直线距离。这样也保证了机房至少会在两个以上的国家分布。 这样自然灾害,战争同时威胁到所有机房的可能性近乎为0.
  2. 保证每个保存的数据都至少有三个拷贝, 每个拷贝在不同的机房。 这样3个拷贝同时坏掉的可能性微乎其微
  3. 为了降低成本,不用raid卡,不用nas。每个存储单元采用pc机, 每个pc机挂4个或更多1TB SATA硬盘, linux系统。 由主控机决定什么数据存储到哪个节点机
  4. 客户可以通过http或ftp访问, 或者专门的开放协议(提供给用户各种语言的sdk), 数据只能添加不能修改,删除(防止用户操作失误)。系统自动的将用户新添加的数据扩散到其他的机房。用户要读取数据时, 系统会自动给他选择一个最近的机房。
  5. 根据用户申请的存储空间收费和读的次数和数据量来收月费。可以推出针对个人的数据备份服务, 价位应该是1G/月 , 1块人民币的样子
  6. 整个数据备份的过程自动进行, 人们只是维护。 维护不需要调整bug, 只要发现哪里有问题,不用修,直接换掉
  7. 随着技术的发展, 硬盘容量的提高, 只要不停的换节点机, 交换器,申请更高的带宽即可

这些应该都没什么不可逾越的技术难度。 微软和google现在都在搞网络硬盘, 应该就有这个意思。设想的这种第三方数据冗灾服务应该不远了,没准早有了,只是我还不知道。

Subversion不完全安装笔记

昨天深夜开始安装Subversion,折腾了很久,终于搞定。 把过程写出来与大家分享,整个安装过程主要参考了 http://www.jlchannel.com/blog/?p=104http://www.newbooks.com.cn/info/52691.html

安装环境为

内核:Linux version 2.6.9-34.ELsmp
操作系统:Red Hat Enterprise Linux AS release 4 (Nahant Update 3)

Web Server: Apache 2.0 ( Web server必须是Apache 2.0以上,Subversion数据库才能通过http协议去访问)

  1. 先到http://subversion.tigris.org 下载最新的文件, 分别是subversion-1.4.0.tar.gz 和 subversion-deps-1.4.0.tar.gz
  2. 将文件包解压
    tar zxvf subversion-1.4.0.tar.gz
    tar zxvf subversion-deps-1.4.0.tar.gz
  3. 开始编译
    cd subversion-1.4.0
    ./congiure
    make
    make install在我用的系统里被安装到了 /usr/local/bin
  4. 编辑http.conf
    加入下面的两行
    LoadModule dav_svn_module modules/mod_dav_svn.so
    LoadModule authz_svn_module modules/mod_authz_svn.so
    DAV svn
    SVNParentPath /data/svn //svn父目录

    Require valid-user //采用何种认证
    AuthType Basic //连接类型设置
    AuthName “Subversion repository” //连接框提示
    AuthzSVNAccessFile /data/svn/accessfile //权限配置文件
    AuthUserFile /data/svn/passwdfile //用户配置文件
  5. 创建数据目录
    cd /data
    mkdir svnsvnadmin create /data/svn/test //创建测试目录

    chown -R nobody /data/svn //很重要,否则从apache访问不了
  6. 管理用户
    htpasswd /data/svn/passwdfile admin //添加用户
  7. 权限设置
    编辑 /data/svn/accessfile
    加入
    [test:/] //这表示,仓库test的根目录下的访问权限
    admin = rw //test仓库admin用户具有读写权限
  8. 重起Apache
    /usr/local/apache/bin/apachectl restart
  9. 服务器端安装完毕
    从http://www.xxxx.com/svn/test 就能够访问了
  10. 安装客户端
    http://tortoisesvn.tigris.org/ 下载TortoiseSVN。一个WIndows资源管理器插件, 把Subversion客户端和资源管理器近乎完美的结合到了一起,现在就可以开始用了。 Let’s GO!

后记:

要注意的还有如下几点:

  1. 服务器端的运行方式除了通过http访问外,还可以是用svn自己的服务器运行,但没有尝试
  2. svn存储数据有两种方式,一种是文件,一种是berklydb, 但是没有让我选择。
  3. Subversion服务器端全靠字符界面来配置,自己手动写配置文件,很麻烦, 尤其是要对整个项目树进行精确的权限管理的时候。 有个Web界面的配置工具 SVNManager,应该能节省很多力气。可惜因为php5安装出现莫名奇妙的问题而没有尝试成功,如果有尝试成功的还请给出测试报告。

try{} catch(…){}

以前都是用try{} catch(…){}来捕获C++中一些意想不到的异常, 今天看了Winhack的帖子才知道,这种方法在VC中其实是靠不住的。例如下面的代码:


try
{
BYTE* pch ;
pch = ( BYTE* )00001234 ; //给予一个非法地址

*pch = 6 ; //对非法地址赋值,会造成Access Violation 异常
}
catch(…)
{
AfxMessageBox( “catched” ) ;
}


这段代码在debug下没有问题,异常会被捕获,会弹出”catched”的消息框。 但在Release方式下如果选择了编译器代码优化选项,则VC编译器会去搜索try块中的代码, 如果没有找到throw代码, 他就会认为try catch结构是多余的, 给优化掉。 这样造成在Release模式下,上述代码中的异常不能被捕获,从而迫使程序弹出错误提示框退出。

那么能否在release代码优化状态下捕获这个异常呢, 答案是有的。 就是__try, __except结构, 上述代码如果改成如下代码异常即可捕获。


__try
{
BYTE* pch ;
pch = ( BYTE* )00001234 ; //给予一个非法地址

*pch = 6 ; //对非法地址赋值,会造成Access Violation 异常
}
__except( EXCEPTION_EXECUTE_HANDLER )
{
AfxMessageBox( “catched” ) ;
}

但是用__try, __except块还有问题, 就是这个不是C++标准, 而是Windows平台特有的扩展。 而且如果在使用过程中涉及局部对象析构函数的调用,则会出现C2712 的编译错误。 那么还有没有别的办法呢?

当然有, 就是仍然使用C++标准的try{}catch(..){}, 但在编译命令行中加入 /EHa 的参数。这样VC编译器不会把try catch模块给优化掉了。

找到一篇比较好的英文文章谈这个问题: http://members.cox.net/doug_web/eh.htm

用C++10 年多了 , 居然这么基础的问题都搞错, 真是汗颜。 要加紧学习啊, Stay Hungry, Stay Foolish!