scourgen

24一/100

Firefox 3.6 性能测试,较Firefox 3.5 性能提高47%!

Firefox 3.6终于发布了,官方发布的Features集中在了宣传新的Personas换肤功能上.其实Personas在去年就开始在Mozilla Addons下载中心提供测试及下载了,Scourgen周围的很多Firefox使用者都用这个插件换了主题.可惜Personas还不支持换标题栏里更换背景图片,只能给标题栏换一个颜色.

而其实3.6最大的改进则提供了HTML5以及极大的增强了JavaScript的性能,而对此官方却没有做太大的介绍,只放了一个演示视频做对比,Scourgen花了点时间对Firefox3.6的JavaScript性能较上一版本(Firefox 3.5.7)做了一个对比,可以发现多数项目都有100%左右的提高,而平均性能提高则达到了47%

分类: IT 继续阅读
22一/101

最新的Adium 1.4hg修改版,支持小i的msn群里显示发言人名字.

Adium不能在小i的msn群里显示发言人的名字,用/showname也没有用,逼得我开着虚拟机用Windows live messenger.

今天看到一篇文章,是讲如何将Adium修改成支持msn群的,但是提供的都是老版本,于是下载了Adium的源码,一步一步进行修改.

  1. 安装Mercurial
    Adium使用Mercurial管理代码,所以得先装这Mercurial.个人建议用mac port进行安装,比较方便.

    sudo port install mercurial
  2. 安装完就可以创建一个工作目录,然后下载Adium的源码了:
    cd ~
    mkdir adium_build
    hg clone http://hg.adium.im/adium
  3. 下载完成后进入Utilities/dep-build-scripts目录
    cd Utilities/dep-build-scripts/
  4. 下载一些相关的包,以下脚本会自动下载10几个包,并且会自动把文件解压到source目录
    ./common.sh -d
  5. 下载Pidgin的源文件并解压缩
    cd source
    mkdir im.pidgin.adium.1-4
    cd im.pidgin.adium.1-4
    wget http://developer.pidgin.im/static/pidgin.mtn.bz2
    bzip2 -d pidgin.mtn.bz2
  6. 因为pidgin是用monotone这个源码管理软件进行管理的,所以我们得再安装monotone
    sudo port install monotone
  7. 然后对monotone的独特项目管理包(.mnt)文件进行解压,得到pidgin的源文件
    mtn db -d pidgin.mtn migrate
    mtn -d pidgin.mtn pull --set-default
    mtn.pidgin.im "im.pidgin.*"
    mtn -d pidgin.mtn co -b im.pidgin.adium.1-4 .
  8. 用monotone更新一下pidgin的代码
    mnt pull
    mnt update
  9. 然后开始build相关联的包
    ./general_dependencies_make.sh
  10. 如果很快就结束的话,多半是有错误发生,可以看一下log文件,比如我就出现了perl里的某个XML Parser包找不到的错误,导致intltool包编译不成功.
    vim ./build/purple_dep_make.log/usr/bin/install -c -m 644 'libgadu.pc' '/Users/scourgen/StudyWorkSpaces/Adium/adium-1.4/Utilities/dep-build-scripts/build/root-i386/lib/pkgconfig/libgadu.pc'
    make[2]: Nothing to be done for `install-exec-am'.
    make[2]: Nothing to be done for `install-data-am'.
    checking for a BSD-compatible install... /usr/bin/install -c
    checking whether build environment is sane... yes
    checking for a thread-safe mkdir -p... /Users/scourgen/StudyWorkSpaces/Adium/adium-1.4/Utilities/dep-build-scripts/source/intltool-0.36.2/install-sh -c -d
    checking for gawk... gawk
    checking whether make sets $(MAKE)... yes
    checking for perl... /opt/local/bin/perl
    <span style="color: #ff0000;">checking for XML::Parser... configure: error: XML::Parser perl module is required for intltool</span>
  11. 于是再调用port安装这个XML Parser
    sudo port install p5-xml-parser
    --->  Computing dependencies for p5-xml-parser
    --->  Fetching p5-xml-parser
    --->  Attempting to fetch XML-Parser-2.36.tar.gz from http://distfiles.macports.org/perl5
    --->  Verifying checksum(s) for p5-xml-parser
    --->  Extracting p5-xml-parser
    --->  Configuring p5-xml-parser
    --->  Building p5-xml-parser
    --->  Staging p5-xml-parser into destroot
    --->  Installing p5-xml-parser @2.36_0
    --->  Activating p5-xml-parser @2.36_0
    --->  Cleaning p5-xml-parser
  12. 再执行第9步,正常的话应该得到如下提示:
    Done - now run ./purple_dependencies_make.sh
  13. 然后开始编译purple的相关包,这步时间会稍微久一点.
    ./purple_dependencies_make.sh
  14. 然后在正式编译purple之前进行修改,加入显示msn群里发言人名字的功能.
    if ((value = msn_message_get_attr(msg, "P4-Context")) != NULL)
    {
    char *body_enc2;
    body_enc2 = g_strdup_printf("<b>***%s***</b>  %s", value,
    body_enc ? body_enc : "");
    g_free(body_enc);
    body_enc = body_enc2;
    }

    将上述代码插入到source/im.pidgin.adium.1-4/libpurple/protocols/msn/msg.c 847行之后,变成:

    842 #if 0
    843         if ((value = msn_message_get_attr(msg, "User-Agent")) != NULL)
    844         {
    845                 purple_debug_misc("msn", "User-Agent = '%s'\n", value);
    846         }
    847 #endif
    848
    849     if ((value = msn_message_get_attr(msg, "P4-Context")) != NULL)
    850     {
    851         char *body_enc2;
    852         body_enc2 = g_strdup_printf("<b>***%s***</b>  %s", value,
    853             body_enc ? body_enc : "");
    854         g_free(body_enc);
    855         body_enc = body_enc2;
    856     }
  15. 然后开始编译LibPurple
    ./purple_make.sh --i386 --regenerate
  16. 然后编译Mac通用的二进制文件
    ./universalize.sh
  17. 然后编译多语言文件
    ./make_po_files.sh
  18. 最后安装新的Frameworks到Adium中
    ./copy_frameworkds.sh
  19. 最后回到Adium的主目录,进行编译
    cd ../..
    make
  20. 完成后,会在主目录的build/Release-Debug目录中出现Adium.app,这就是最终的可执行文件了.
    打开程序,看看效果.

    不错吧,已经可以看到3个*中间的发言人名字了.

为了方便大家,这里提供我编译的版本的下载地址,是基于最新的1.4hg进行修改的,直接下载就能用了

Adium 1.4hg Scourgen编译版

分类: IT 1个评论
21一/100

用Python脚本抓取Linkedin中的公司信息

Linkedin是一个在国外比较知名的商务型SNS.最近在研究Linkedin时,发现Linkedin在添加个人信息时的公司名称提示功能很强大,通过这个功能几乎可以获取一份大型公司名录.于是用Python花了几分钟写了一个小脚本,顺利的获取到了6000余条公司信息.

代码如下:

import urllib2
import json
import MySQLdb

db = MySQLdb.connect(host="localhost",unix_socket='/Applications/MAMP/tmp/mysql/mysql.sock',port=3306,user="root",passwd="000000",db="linkedin_spider")
db.set_character_set("utf8")

def getData(str):
 req = urllib2.Request(
 url = 'http://www.linkedin.com/typeaheadv3/company?query='+str+'&loc=P'
 )
 result = urllib2.urlopen(req).read()
 b= json.JSONDecoder().decode(result)
 for k in b["resultList"]:

 cursor = db.cursor()
 if k.has_key("imageUrl"):
 sql = u"insert into companys values(null,\""+k['displayName'].replace('"','\\"')+"\",\""+k['subLine'].replace('"','\\"')+"\",\""+k["headLine"].replace('"','\\"')+"\",\""+k['imageUrl']+"\",\""+k['url']+"\",\""+k['id']+"\")"
 else:
 sql = u"insert into companys values(null,\""+k['displayName'].replace('"','\\"')+"\",\""+k['subLine'].replace('"','\\"')+"\",\""+k["headLine"].replace('"','\\"')+"\",\"null\",\""+k['url']+"\",\""+k['id']+"\")"
 print sql
 cursor.execute(unicode(sql))
 print k['displayName']

a="abcdefghijklmnopqrstuvwxyz"
i=0
for x in a:
for y in a:
 print i
 i=i+1
 getData(x+y)

MySQL数据库结构:

SET NAMES utf8;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
--  Table structure for `companys`
-- ----------------------------
DROP TABLE IF EXISTS `companys`;
CREATE TABLE `companys` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `displayName` varchar(500) COLLATE utf8_bin DEFAULT NULL,
 `subLine` varchar(500) COLLATE utf8_bin DEFAULT NULL,
 `headLine` varchar(500) COLLATE utf8_bin DEFAULT NULL,
 `imageUrl` varchar(500) COLLATE utf8_bin DEFAULT NULL,
 `url` varchar(500) COLLATE utf8_bin DEFAULT NULL,
 `link_id` varchar(500) COLLATE utf8_bin DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=0 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

关键字设置的很简单,从aa循环到zz,每个关键字能够搜到10条信息,所以不考虑数据重复性的话,这个程序一共能够抓取到26*26*10=6760条公司信息.而实际运行结果则是插入了6518条,而其中34条是重复数据,可见Linkedin的公司数量非常之多.

需要注意的几个问题:

  • Linkedin公司介绍中有西欧字符,默认情况下无法插入sql,报错
    Traceback (most recent call last):
     File "main.py", line 29, in <module>
     getData(x+y)
     File "main.py", line 21, in getData
     cursor.execute(sql)
     File "/opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/MySQLdb/cursors.py", line 149, in execute
     query = query.encode(charset)
    <span style="color: #ff0000;">UnicodeEncodeError: 'latin-1' codec can't encode character u'\u0142' in position 89: ordinal not in range(256)</span>
    smbp:Linkedin_Spider scourgen$ python2.6 main.py
    /opt/local/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/site-packages/MySQLdb/__init__.py:34: DeprecationWarning: the sets module is deprecated
     from sets import ImmutableSet

    解决办法是将sql字符串转换成utf8,同时也将数据库的连接属性改成utf8即可

    #设置连接属性:
    db.set_character_set("utf8")
    #u"" 代表将字符串转成unicode
    sql=u"insert ..."
    #再转一次,以防万一
    cursor.execute(unicode(sql))
    
  • 公司简介中有些数据含有引号,导致sql语句构造失败
    replace('"','\\"')可以将"替换成\",以便构造sql语句
    sql = "insert ...."+k['subLine'].replace('"','\\"')
21一/100

实测Bootcamp 3.1,显卡性能大幅度提高

Apple发布了虚拟化软件Bootcamp的3.1版本,在这个版本中,除了正式支持了Windows 7之外,最明显的改进就是极大地提高了显卡的性能。

显卡驱动升级到了188.61

而在我的MacBook Pro上的Windows 7的显卡评分也从3.0时的5.9 5.3提高到了6.4 6.4


升级前


升级后

分类: IT 没有评论
19一/101

JavaScript Templates(JST),JavaScript语言下的模板引擎

JavaScript Templates(简称JST)是TrimPath开发的一款JavaScript语言的模板引擎,它可以在任何网页的前端使用,并用来处理大量的,实时的数据的前台展示.JST也是vivipos的打印模板处理引擎.

JST使用的语言是JavaScript,而使用的数据格式则是普通的JSON格式.

简单示例:

<div id="tpl_id">Hello <b>${name}</div>
<script language="javascript" src="trimpath/template.js"></script>
<script>
var a={name:"scourgen"};
alert(TrimPath.processDOMTemplate("tpl_id", a));
</script>

则会alert出scourgen.

JST支持一下几种语法:

  • 变量判断:
     ${name|default:"is null"} 
  • 语句判断
    {if name=="scourgen"}
    scourgen is here
    {else}
    no people
    {/if}
    
  • 赋值
    {var nameList=["scourgen","John","Shelly"]} 
  • 循环
    {for name in nameList}
    Hello ${name}!
    {/for}
     
  • 宏操作
    //借用官方的例子:</li>
    </ul>
    <a name="Macro_Declarations">  Examples:
    {macro htmlList(list, optionalListType)}
    {var listType = optionalListType != null ? optionalListType : "ul"}
    <${listType}>
    {for item in list}
    <li>${item}</li>
    {/for}
    </${listType}>
    {/macro}
    
    Using the macro...
    ${htmlList([ 1, 2, 3])}
    ${htmlList([ "Purple State", "Blue State", "Red State" ], "ol")}
    {var saved = htmlList([ 100, 200, 300 ])}
    ${saved} and ${saved}</a>
  • 执行JS
    //借用官方的例子:</li>
    </ul>
    <a name="eval_blocks">  <select onchange="sel_onchange()"></select>
    {eval}
    sel_onchange = function() {
    ...Do some complicated javascript...;
    ...more js code here...;
    }
    {/eval}</a>
  • HTML属性/CSS压缩

    //借用官方的例子:
    <a name="minify_blocks"> <select onchange="{minify}
    ...Do some complicated multi-line javascript...;
    ...more js code here...;
    this.enabled = false;
    {/minify}">
    <select onchange="{minify END_OF_JS}
    ...Do some complicated multi-line javascript...;
    ...more js code here...;
    this.enabled = false;
    END_OF_JS"></a>

用JST的好处

  1. 提高性能:对于大数据量的,需要及时处理的数据操作,大可将数据的处理放到前台,减轻后台压力
  2. JST语法简单,JST的语法和Smarty,Velocity类似,如果有以上模板系统开发经验的话,可以马上上手.
  3. 增加系统扩展性,提供另外一种Model到View的途径
  4. JST速度极快
    我用官方的demo作了两个测试,数据量分别是5和1000
    数据量为5条记录时:

    数据量为1000条记录时:

    可以看到,虽然记录数量增长了200倍,而运行时间和程序堆栈执行次数却只增长了39倍和117倍,而通过对Profile进行进一步分析,可以看出大部分时间是在入口函数以及DOM操作上,足以得出结论:JST的性能是很适合对大容量的数据进行处理的.

分类: IT 1个评论
13一/100

谈谈VIVIPOS的市场定位和应用

去年开发vivipos时,Scourgen曾被公司派遣到台湾与FEC的vivipos团队共同工作过一段时间,通过短短十几天的时间,Scourgen很惊讶台湾的拼搏精神,同时也被vivipos的技术架构以及商业模式给吸引,这篇文章主要谈谈vivipos的背景以及市场定位.

vivipos是一台收银机,它的市场定位是收银机的中低端市场,主要客户群是中小型的零售商,这个用户群体可不像沃尔玛,苏宁那么阔气,它们才开了几家分店,用着老式的收银机,老板每天在多家店面内辗转,它们用传真机和excel统计销售额,人工进行补货,节约是他们共同的特征,在眼下,把每一分钱用在刀刃上.谁知道还会不会有下一波经济危机和另一个8万亿?它们在某种程度上是成功的,它们在国内零售业强大的内需中找到了一小片属于自己的市场份额,但它们的老板多半没有太多的零售经验,靠着积攒十几年的打工辛苦钱,或拿个同村乡亲们的集资,又或卖了大城市里的房子,靠着自己的勤劳和草根智慧,做起了属于他们自己的事业.

而如果入行早一点,可能做到现在有了50甚至100家分店,经过几次挣扎后管理方式终于初步转向了电子化,可能上过了系统,可能换过收银机,也可能做过几个网站,注册过中文域名也在百度上投过广告,但是效果始终不是那么美好,常想着为什么辛香汇的网站就比我火?为啥巴贝拉的毛利能达到70%?老板们后面始终跟着刚毕业的销售,享受着大学生们刚学会几天不久的马屁的同时觉得耐克,肯德基也没什么大不了,不就比我早做了几十年么.

中小零售行业市场是庞大的,毕竟沃尔玛再大也不可能在每个城乡里都开一个.而它们的增长性又是惊人地,只要给与他们适当的帮助,帮助他们解决零售的货源,分销,店面,顾客关系等几个最重要的问题后,它们会用高达3位数的年增长率百分比告诉你,老板又换了一辆奔驰.

而对与这个激动人心又充满无限增长潜力的传统行业,IT信息技术如何帮助其解决经营中的问题,帮助企业快速增长呢?

我们都知道用信息技术好,可是好在哪里,到底什么是信息技术,它具体能解决什么问题,在某一个特定的环境下到底能给老板们带来怎么样的利益,这才是中小型零售商最关心的问题.大的概念也不用说,饼也不用画,我们一五一十把事情说明白就行.

  1. IT产品的接受能力
    在这个把用破解软件当作习惯的地方,可千万别说你是卖软件的.在这儿软件不值钱.Windows 7在大街上才卖5块钱,凭什么要我付几万块的钱来买你这个根本没人用的软件?
    要不你是大型的专业软件开发公司,要不你遇上的是大型的业余凯子,不然可千万别谈什么软件.我保证他们愿意花3万元的单价买IBM的老式收银机,也不会来你这儿买你花了200个人月开发的新一代管理软件.
    那咋办?
    捆绑销售!
    vivipos的硬件成本不高,采用via 1G的CPU以及1G的内存,加上1G的CF卡作为唯一的储存器当硬盘用,加上15寸的触摸屏,整体成本想想就知道不是很高,要知道,主要成本在于开发操作系统以及应用平台的软件上了,而对于vivipos来说,它的软件平台甚至是开源的,但是这套软件只能运行在vivipos的硬件上.这属于用着开源的名义赚整体的利润,不过即使动机不纯,在相对垄断的POS机行业,6000元的售价也是极为诱人的了,要知道IBM的POS机,最便宜的可也没有下5位数的啊.
  2. 开店成本
    传统POS行业中,如果要上一套系统,可能牵涉到大大小小数个公司,有的提供硬件,有的提供操作系统,有的提供软件,有的提供实施,有的提供服务,等等等等,总之挺简单的事情总是最后搞的很复杂,什么A的硬件不兼容B的软件了,C对D的部署方式不认可,不提供保修了,等等乱七八糟一大堆问题,而没有一家公司能够站出来对这些设备和软件完全负责,往往出了不同的问题要找不同的人.而将方案总的包给某个集成商也不能往往也不能完全解决的问题,反而增加了一道中间手续.虽然出了问题时打继承商的维修电话,听筒里的mm说话的语调总是嗲得让你发不了脾气,但终究还是不能解决问题,如果有一家公司能提供所有的这些产品和服务就好了,俗话叫啥?一条龙服务!
    vivipos就采取了一家搞定的策略,一个国家就一个总代,硬件就2种,一个15寸的一个12寸的,除了屏幕不一样别的没区别,软件都是开源的,功能丰富界面美观,抱回家10分钟就能自学成才,想学Linux还能进vivipos的开发模式打几个命令小试一下伸手,软件出了问题自动截图上传服务器,再不行打个电话让支持中心远程界面操控你的界面,你机器上有什么问题他看得一清二楚.
    所以不但开店成本下降了,服务成本也下降了许多.但您千万别拿台300块的收银机和vivipos比,级别不一样,夸收银机好用的老板们根本不是目标客户.
  3. 信息化
    上设备,上系统的意义是啥?提高工作效率.
    在零售业态变化天翻地覆的今天,谁都不能保证我的那一亩三分地明天不会变成二亩六,如果你有一个好的什口,在本店内进行重新装修,扩大营业面积是一个最好的办法.
    可等等,我的设备怎么办?
    对于传统设备来说,要不就是单点独用,和其他设备老死不相往来,要不就是动则一个大系统,终端支持数千并发,却不允许终端的应用随着业务的变化而变化,比如在营业面积增大的情况下,如何通过简单的购买一台新设备却能够动态的接入旧的系统?举个简单的例子,我买了台新的收银机,能不能让它和我以前的那台共享一个打印机?能不能在钱箱满的时候通知其他终端?厨房菜做完了能不能告诉前台派个人来送餐??能不能.....IBM不老在吹什么"智能的XX",什么"应需而变"嘛?别听它瞎扯,能够解决具体问题的才是对你有用的,听IBM的话,把你卖了都不够塞它牙缝的.
    而vivipos却可以做到,它基于RoR的Scaffold理念,能够极为快速的配置出你所要的应用,而离散式的基于文件的数据库则使数据的远程即时传输成为可能,更为吸引人的则是它的网络节点概念:每一个vivipos都是一个节点,对于每一个节点,只有上级和下级的关系,对于上级节点,上传数据,对于下级节点,下发数据,如果办公室有一台vivipos,则可以将这台vivipos配置成最上级节点,不通过任何开发就可以看到下属所有节点的销售情况,及时的哟!
13一/100

MySQL性能调优 – 使用更为快速的算法进行距离计算

最近遇到了一个问题,通过不断的尝试最终将某句原本占据近1秒的查询优化到了0.01秒,效率提高了100倍.

问题是这样的,有一张存放用户居住地点经纬度信息的MySQL数据表,表结构可以简化为:id(int),longitude(long),latitude()long. 而业务系统中有一个功能是查找离某个用户最近的其余数个用户,通过代码分析,可以确定原先的做法基本是这样的:

//需要查询的用户的坐标

$lat=20;
$lon=20;
//执行查询,算出该用户与所有其他用户的距离,取出最近的10个
$sql='select * from users_location order by ACOS(SIN(('.$lat.' * 3.1415) / 180 ) *SIN((latitude * 3.1415) / 180 ) +COS(('.$lat.' * 3.1415) / 180 ) * COS((latitude * 3.1415) / 180 ) *COS(('.$lon.' * 3.1415) / 180 - (longitude * 3.1415) / 180 ) ) * 6380  asc limit 10';

而这条sql执行的速度却非常缓慢,用了近1秒的时间才返回结果,应该是因为order里的子语句用了太多的数学计算公式,导致整体的运算速度下降.

而在实际的使用中,不太可能会发生需要计算该用户与所有其他用户的距离,然后再排序的情况,当用户数量达到一个级别时,就可以在一个较小的范围里进行搜索,而非在所有用户中进行搜索.

所以对于这个例子,我增加了4个where条件,只对于经度和纬度大于或小于该用户1度(111公里)范围内的用户进行距离计算,同时对数据表中的经度和纬度两个列增加了索引来优化where语句执行时的速度.

最终的sql语句如下:

$sql='select * from users_location where
latitude&gt;'.$lat.'-1 and
latitude&lt;'.$lat.'+1 and
longitude&gt;'.$lon.'-1 and
longitude&lt;'.$lon.'+1
order by ACOS(SIN(('.$lat.' * 3.1415) / 180 ) *SIN((latitude * 3.1415) / 180 ) +COS(('.$lat.' * 3.1415) / 180 ) * COS((latitude * 3.1415) / 180 ) *COS(('.$lon.' * 3.1415) / 180 - (longitude * 3.1415) / 180 ) ) * 6380  asc  limit 10';

经过优化的sql大大提高了运行速度,在某些情况下甚至有100倍的提升.这种从业务角度出发,缩小sql查询范围的方法也可以适用在其他地方.

12一/100

MySQL性能调优 – 使用UNION ALL代替UNION

最近遇到了一个MySQL性能调优的问题,在数据库中有一张主要用了2个UNION来联合3张表的视图,而所有对于这个视图的查询反应都很慢,经过一步步的调试(说句题外话,用SQLYog来调试MySQL真的很方便),最终确定问题出在这个视图里所用的UNION上。

查了查MySQL的文档,这么说到

The default behavior for UNION is that duplicate rows are removed from the result. The optional DISTINCT keyword has no effect other than the default because it also specifies duplicate-row removal. With the optional ALL keyword, duplicate-row removal does not occur and the result includes all matching rows from all the SELECT statements.

You can mix UNION ALL and UNION DISTINCT in the same query. Mixed UNION types are treated such that a DISTINCT union overrides any ALL union to its left. A DISTINCT union can be produced explicitly by using UNION DISTINCT or implicitly by using UNION with no following DISTINCT or ALL keyword.

举个例子:

如果union两个不同的select,最终的结果则是2个select的集合:

select 1 union select 2;
+---+
| 1 |
+---+
| 1 |
| 2 |
+---+
2 rows in set (0.00 sec)

而如果union的对象包含重复的数据,例如下条语句包含了两个select 2,默认则会去除重复部分:

select 1 union select 2 union select 2;
+---+
| 1 |
+---+
| 1 |
| 2 |
+---+
2 rows in set (0.00 sec)

而如果将上条语句改为union all的话,则可以显示所有的结果,包含重复部分:

select 1 union all select 2 union all select 2;
</strong>+---+
| 1 |
+---+
| 1 |
| 2 |
| 2 |
+---+
3 rows in set (0.00 sec)

可以看到,union和union all的差别就在于union会对数据做一个distanct的动作,而这个distanct动作的速度则取决于现有数据的数量,数量越大则时间也越慢。而对于几个数据集,要确保数据集之间的数据互相不重复,基本是O(n)的算法复杂度。

有了理论依据后,便动手更改view的结构,在确保数据逻辑上不会有重复情况出现后,将2个union都改成了union all,query的反应速度从1.7秒变成了300毫秒左右,耗费时间只有以前的17%。

12一/100

Apple store的真实收入

最近看到一些新闻,标题是《Gameloft:18 个月,1000 万次付费下载》

比如 Gameloft,在其美国时间 1 月 7 日发布的新闻稿中,其董事长兼 CEO Michel Guillemot 宣布它已经获得了1000 万付费下载。按 Gameloft 的游戏大多分布在 4.99 到 6.99 的价格计,它在 18 个月内获得 5000 万美元的收入是不成问题的。

平均售价6美金,1000万次付费下载,收入是否真的就等于5000万美元?

这不是一个简单的乘法。

Scourgen的朋友Jacky曾经是苹果的粉丝,他曾经告诉我有一种gift card可以在淘宝上买到,这种gift card可以用rmb购买,再兑换成购买价格几十倍的app store内的美金。于是我在淘宝上以“app store”为关键字进行了搜索,搜索结果竟然有1119条,而多数宝贝都是以35人民币的价格贩卖100美金的充值面额,也就是说你花35人民币,以原来5%的价格(35人民币 除以 (6.8汇率 乘以 100美金) =5.15%),就可以在app store上买总计100美金的应用程序,如果算做5美金一个应用程序的话,则可以用35元买20个应用程序,折合每个1.75元。花2块钱不到买一个在iphone上运行的正版软件,真是非常吸引人的事情,难怪scourgen随便打开几个宝贝,发现每个宝贝的成交都有10个以上,看来好多人已经用这种方法去购买app store内的软件了。

我想,任何一个人如果知道可以通过这种方法以低价购买app,他们肯定不会继续以20倍的价格继续购买app了吧?

做一个悲观的假设,如果所有购买gameloft的app的用户都使用这种方法进行购买,则gameloft真实的收入是多少呢?1000万次付费下载,每次1.75元(0.26美元),则是260万美元。260万美元,看起来还真不少,等等,你忘记了apple!因为根据app store与应用程序开发商的协议,所有程序销售额的30%均需要给apple分成,所以gameloft拿可怜的260万美金收入还得打7折,也就是182万美元。

新闻稿的5000万美元和182万美元之间可是差太多了,这是否代表着现在的app store并没有想象中的那么美好?做iphone程序可能真的不怎么赚钱。

分类: IT 没有评论
12一/100

6款PHP论坛大比拼之 性能比较

因为工作需要,需要在现有的网站上部署一个论坛以供用户使用,所以对目前较为著名的6款php论坛进行了一个评测.

这6款论坛分别是:
phpBB v3
bbPress 1.0
phorum 5.2.14
vanilla 1.1.10
IP.Board v3.0.4
vBulletin Suite (VBB) v4

而之所以没有考虑phpwind,discuz等国内著名论坛,主要是因为语言支持和安全方面的考虑.

在测试之前,我已经将6款forum的最新版本安装到了我的MacBook Pro上,用MAMP作为服务程序,提供一个统一软件的平台.

安装完之后,先进行一下简单的性能测试:

#ab -n 100000 -c 100 $url

name     xcache     apc

phpbb3 152  113

bbpress 45  50

phorum 184 189

vanilla 119 125

ipb 64 60

vbb 59 56

可以看到速度最快的是phorum,可是phorum提供的功能确不够充分,属于短小精悍形的论坛程序,如果您的需求只是速度至上,那么phorum应该是你的不二选择。

在这里必须表扬一下vbb,vbb在严苛的功能需求和性能之间做到了完美的平衡,虽然它是历史最悠久,功能最强大的论坛之一,但是运行速度却丝毫不差前几位轻量级选手,我用xcache观察到vnn在处理论坛默认页时只include了15个文件,而耗费的内存不超过3m,这在php程序里可以算是大型程序一个优化到极致的典型了吧!

所以关于性能上的选择,如果还是需要考虑到兼备功能的话,scourgen强力推荐vbb,否则可以考虑phpbb3以及vanilla,而如果您追求极致的速度,phorum则是你的不二之选。

分类: php 没有评论