京山游俠

          專(zhuān)注技術(shù),拒絕扯淡
          posts - 50, comments - 868, trackbacks - 0, articles - 0
            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

          Web 2.0時(shí)代,決戰(zhàn)效率之巔

          Posted on 2009-04-18 22:17 京山游俠 閱讀(3876) 評(píng)論(9)  編輯  收藏 所屬分類(lèi): Linux和Java
          在這個(gè)博客上晃悠的,大部分都是Java的忠實(shí)粉絲。大家都知道Java開(kāi)發(fā)Web應(yīng)用的眾多優(yōu)點(diǎn),有大量開(kāi)源的穩(wěn)定的應(yīng)用服務(wù)器,有大量開(kāi)源的穩(wěn)定的開(kāi)發(fā)庫(kù)。以前在開(kāi)發(fā)效率上Java比不上動(dòng)態(tài)語(yǔ)言,但是現(xiàn)在出現(xiàn)了數(shù)都數(shù)不清的開(kāi)發(fā)框架,讓我們使用Java進(jìn)行Web開(kāi)發(fā)的效率突飛猛進(jìn),直逼動(dòng)態(tài)語(yǔ)言。

          然而在Web 2.0時(shí)代,Java一定是最優(yōu)秀的嗎?

          在Web 2.0時(shí)代,大家都有點(diǎn)在效率方面的偏執(zhí),不斷有人在挑戰(zhàn)極限,他們追求更大的并發(fā)鏈接數(shù),他們追求更加快的處理速度。操作系統(tǒng)覺(jué)得select不夠快,于是出現(xiàn)了IOCP、epoll、kqueue等系統(tǒng)調(diào)用;Web服務(wù)器的開(kāi)發(fā)者們覺(jué)得Apache httpd不夠快,于是出現(xiàn)了lighttpd、nginx。使用上Fedora 10之后,我就不斷用yum list命令企圖發(fā)現(xiàn)一些驚奇。在這樣的探索中,我發(fā)現(xiàn)了Fedora 10中安裝lighttpd和nginx是多么簡(jiǎn)單,也發(fā)現(xiàn)使用Fast CGI開(kāi)發(fā)也是那么順手。下圖中是我用yum list命令發(fā)現(xiàn)的一些軟件包
          yum_list.png


          于是,在我的心中出現(xiàn)了一個(gè)疑問(wèn):httpd、lighttpd、nginx、tomcat哪一個(gè)更快呢?

          我使用PHP寫(xiě)了一個(gè)小程序,以便測(cè)試上面的Web服務(wù)器哪一個(gè)更快,tomcat是Java的服務(wù)器,不能運(yùn)行PHP,只能運(yùn)行JSP。我的程序是這樣設(shè)計(jì)的:先生成1個(gè)長(zhǎng)度為1000個(gè)單詞、每個(gè)單詞長(zhǎng)度為1-10個(gè)字母的字符串,再生成1000個(gè)長(zhǎng)度為10個(gè)單詞、每個(gè)單詞長(zhǎng)度為1-10個(gè)字母的字符串,然后對(duì)這些字符串排序,輸出。為什么這么設(shè)計(jì)呢?因?yàn)槲矣X(jué)得這比較接近Web 2.0的真實(shí)使用環(huán)境,一個(gè)1000字長(zhǎng)度的文章加上1000個(gè)10字長(zhǎng)度的評(píng)論,這不是我們最常見(jiàn)的嗎?而且這個(gè)程序中會(huì)多次調(diào)用rand()函數(shù),會(huì)多次進(jìn)行字符串連接操作,會(huì)對(duì)字符串進(jìn)行排序,這些操作對(duì)語(yǔ)言的執(zhí)行速度也是一個(gè)考驗(yàn)。

          先來(lái)看代碼,test.php:
          <?php
          ??
          //?定義隨機(jī)生成字符串的函數(shù)
          ??function?make_string($word_count,$word_length){
          ????
          $letters?=?range('a','z');
          ??????
          $temp_string?=?'';
          ??????
          for($i=0;?$i<$word_count;?$i++){
          ????????
          $temp_word?=?'';
          ????????
          for($j=0;?$j<$word_length;?$j++){
          ??????????????
          $temp_word?=?$temp_word.$letters[rand(0,25)];
          ????????}
          ????????
          $temp_string?=?$temp_string.'?'.$temp_word;
          ??????}
          ??????
          return?$temp_string;
          ??}
          ??
          ??
          //?定義隨機(jī)數(shù)種子,以便每次運(yùn)行測(cè)試,都生成相同的內(nèi)容
          ??srand(1);
          ??
          ??
          //?首先生成一個(gè)包含一千個(gè)單詞的字符串,每個(gè)單詞長(zhǎng)度為1到10個(gè)字母
          ??$strings[0]?=?make_string(1000,rand(1,10));
          ??
          ??
          //?再生成1000個(gè)包含10個(gè)單詞的字符串,每個(gè)單詞的長(zhǎng)度為1到10個(gè)字母
          ??for($i=0;?$i<1000;?$i?++){
          ??????
          $strings[$i+1]?=?make_string(10,rand(1,10));
          ??}
          ??
          ??
          //?排序,輸出
          ??sort($strings);
          ??
          for($i=0;?$i<1001;?$i++){
          ????
          echo?$strings[$i].'<br><br>';
          ??}
          ?>

          執(zhí)行情況如何呢?先讓大家看三個(gè)圖。這是我分別使用httpd、lighttpd、nginx做為服務(wù)器時(shí),使用
          ab?-c?100?-n?10000?http://localhost/test.php
          命令進(jìn)行測(cè)試所得到的結(jié)果:
          015.png

          006.png

          009.png

          其中,httpd是以mod_php的方式運(yùn)行PHP,而其它兩個(gè)用的是FastCGI的方式運(yùn)行PHP。從速度上來(lái)講,httpd略占優(yōu)勢(shì)。但是httpd占用的資源太多,而且很難支持大的并發(fā)連接數(shù)。當(dāng)并發(fā)數(shù)增加到1000的時(shí)候,httpd就反應(yīng)不過(guò)來(lái)了,出現(xiàn)超時(shí);而lighttpd和nginx都可以輕松支持到30000的并發(fā)。注意,如果使用超過(guò)1000的并發(fā)來(lái)進(jìn)行測(cè)試,千萬(wàn)別忘了使用ulimit命令來(lái)設(shè)置進(jìn)程可以打開(kāi)的最大文件數(shù)。

          到了這里我就想,如果使用C++編寫(xiě)Fast CGI程序,運(yùn)行的速度是不是更快呢。使用Java呢?于是我用C++和Java分別實(shí)現(xiàn)了和上面功能相同的程序。代碼如下:
          #include?<fcgi_config.h>
          #include?
          <unistd.h>
          #include?
          <cstdlib>
          #include?
          <string>
          #include?
          <vector>
          #include?
          <algorithm>
          #include?
          <fcgi_stdio.h>?/*?fcgi?library;?put?it?first*/

          using?namespace?std;

          string?make_string(int?word_count,int?word_length){
          ????
          char?letters[]?=?"abcdefghijklmnopqrstuvwxyz";
          ????
          string?temp_string;
          ????
          for?(int?i?=?0;?i?<?word_count;?i++)?{
          ????????
          string?temp_word;
          ????????
          for?(int?j?=?0;?j?<?word_length;?j++)?{
          ????????????
          int?index?=?rand()?%?26;
          ????????????temp_word.append(
          1,?letters[index]);
          ????????}
          ????????temp_string.append(
          "?");
          ????????temp_string.append(temp_word);
          ????}
          ????
          return?temp_string;
          }

          int?main?()
          {
          ????
          while?(FCGI_Accept()?>=?0)?{

          ????????
          char?*contentLength?=?getenv("CONTENT_LENGTH");
          ????????
          int?len;

          ????????printf(
          "Content-type:?text/html\r\n"
          ????????????
          "\r\n");

          ????????
          if?(contentLength?!=?NULL)?{
          ????????????len?
          =?strtol(contentLength,?NULL,?10);
          ????????}?
          else?{
          ????????????len?
          =?0;
          ????????}

          ????????
          if?(len?<=?0)?{
          ????????????printf(
          "No?data?from?standard?input.<p>\n");
          ????????}?
          else?{
          ????????????
          int?i,?ch;

          ????????????printf(
          "Standard?input:<br>\n<pre>\n");
          ????????????
          for?(i?=?0;?i?<?len;?i++)?{
          ????????????????
          if?((ch?=?getchar())?<?0)?{
          ????????????????????printf(
          ????????????????????????????
          "Error:?Not?enough?bytes?received?on?standard?input<p>\n");
          ????????????????????
          break;
          ????????????????}
          ????????????????putchar(ch);
          ????????????}
          ????????????printf(
          "\n</pre><p>\n");
          ????????}

          ????????vector
          <string>?strings;
          ????????strings.push_back(make_string(
          1000,?rand()?%?10?+?1));
          ????????
          for?(int?i?=?0;?i?<?1000;?i++)?{
          ????????????strings.push_back(make_string(
          10,?rand()?%?10?+?1));
          ????????}

          ????????sort(strings.begin(),?strings.end());

          ????????
          for?(vector<string>::iterator?it?=?strings.begin();?it?!=?strings.end();?it++)?{
          ????????????printf(
          "%s<br><br>",?(*it).c_str());
          ????????????printf(
          "\r\n");
          ????????}

          ????}?
          /*?while?*/

          ????
          return?0;
          }

          JSP:
          <%@?page?language="java"?contentType="text/html;?charset=UTF-8"
          ????pageEncoding
          ="UTF-8"%>
          <%@?page?import="java.util.Random"?%>
          <%@?page?import="java.util.Arrays"?%>
          <!DOCTYPE?html?PUBLIC?"-//W3C//DTD?HTML?4.01?Transitional//EN"?"http://www.w3.org/TR/html4/loose.dtd">
          <html>
          <head>
          <meta?http-equiv="Content-Type"?content="text/html;?charset=UTF-8">
          <title>Insert?title?here</title>
          </head>
          <body>
          <%!
          public?String?make_string?(?int?word_count,int?word_length)?{
          ????Random?rand?
          =?new?Random();
          ????
          char?letters[]?=?"abcdefghijklmnopqrstuvwxyz".toCharArray();
          ????String?temp_string?
          =?"";
          ????
          for?(int?i?=?0;?i?<?word_count;?i++)?{
          ????????String?temp_word?
          =?"";
          ????????
          for?(int?j?=?0;?j?<?word_length;?j++)?{
          ????????????
          int?index?=?rand.nextInt(26);
          ????????????temp_word?
          +=?Character.toString(letters[index]);
          ????????}
          ????????temp_string?
          +=?"?";
          ????????temp_string?
          +=?temp_word;
          ????}
          ????
          return?temp_string;
          }
          %>
          <%
          Random?rand?
          =?new?Random();

          String[]?strings?
          =?new?String[1001];
          strings[
          0]?=?make_string(1000,rand.nextInt(10)+1);
          for(int?i=1;?i<1001;?i++){
          ????strings[i]?
          =?make_string(10,rand.nextInt(10)+1);
          }
          Arrays.sort(strings);

          for(int?i=0;?i<1001;?i++){
          %>
          <%=strings[i]%><br><br>
          <%
          }

          %>
          </body>
          </html>

          這時(shí)候,我使用lighttpd作為服務(wù)器運(yùn)行PHP和Fast CGI,使用Tomcat運(yùn)行JSP,得到如下的測(cè)試結(jié)果:

          先看JSP,我使用的測(cè)試命令是ab -c 100 -n 10000 http://localhost:8080/test.jsp,測(cè)試的結(jié)果只有29.30req/s,如下圖
          java_result.png
          這個(gè)時(shí)候的資源占用是多少呢,請(qǐng)看top命令的截圖:
          java_top.png
          java進(jìn)程只占用了470兆的內(nèi)存,CPU基本占滿(mǎn)了,那是因?yàn)槲覍?xiě)的這個(gè)程序?qū)PU使用比較高。

          再來(lái)看看PHP執(zhí)行的情況,測(cè)試命令為ab -c 100 -n 10000 http://localhost/test.php,測(cè)試結(jié)果有48.73req/s,如下圖:
          php_result.png

          資源占用有多少呢,再來(lái)看看top命令的截圖
          php_top.png

          每個(gè)php-cgi進(jìn)程用4M內(nèi)存,lighttpd服務(wù)器占用5M內(nèi)存,而我的機(jī)器上跑了72個(gè)php-cgi進(jìn)程,如下圖:

          php_procs.png

          總內(nèi)存占用293M,CPU占用也比較高。

          使用C++寫(xiě)的Fast CGI,測(cè)試命令為ab -c 100 -n 10000 http://localhost/test.fcgi,結(jié)果為266.47req/s,是PHP的5倍多,是JSP的9倍。
          fcgi_result.png

          top截圖,發(fā)現(xiàn)C++寫(xiě)的test.fcgi每個(gè)進(jìn)程只占1M內(nèi)存:
          fcgi_top.png

          總共有64個(gè)test.fcgi進(jìn)程:

          fcgi_procs.png

          總內(nèi)存占用只有79M,CPU占用也比較低,沒(méi)有達(dá)到滿(mǎn)載。

          討論:

          先來(lái)說(shuō)說(shuō)服務(wù)器,對(duì)于Web 2.0的應(yīng)用來(lái)說(shuō),httpd基本上可以淘汰了,資源占用太高,支持不了上千的并發(fā)請(qǐng)求。lighttpd和nginx在FastCGI上的表現(xiàn)都很不錯(cuò),從性能上說(shuō),nginx似乎還要強(qiáng)一些,但是缺點(diǎn)就是文檔不完善,nginx需要lighttpd提供的spawn-fcgi程序來(lái)啟動(dòng)Fast CGI進(jìn)程,而且不知道對(duì)Fast CGI負(fù)載均衡的支持怎么樣,因?yàn)槲以诰W(wǎng)上找了很久都沒(méi)有找到相關(guān)的文檔。而lighttpd的文檔就完善多了,雖然是英文的,但讀起來(lái)不難。我已經(jīng)把lihgttpd的文檔都讀了一遍了,對(duì)于fastcgi.txt和performance.txt我還反復(fù)閱讀,這些文檔對(duì)于Fast CGI的配置和功能有不錯(cuò)的描述。所以,如果選擇Web服務(wù)器,我的答案是lighttpd。

          再來(lái)說(shuō)說(shuō)編程語(yǔ)言。速度最快的無(wú)疑是C++,它是Java的9倍,是PHP的5倍。這里就有一點(diǎn)奇怪了,Java是編譯型語(yǔ)言,而PHP是解釋的,在我的測(cè)試中,沒(méi)有對(duì)PHP使用字節(jié)碼緩存,結(jié)果編譯型的語(yǔ)言居然跑不過(guò)解釋型的。有人也許會(huì)說(shuō),PHP開(kāi)了70幾個(gè)進(jìn)程,而Tomcat只有一個(gè)進(jìn)程,但是不管怎么樣,CPU都是滿(mǎn)載的,就算多開(kāi)幾個(gè)Tomcat進(jìn)程,也不可能把一個(gè)CPU當(dāng)兩個(gè)用。當(dāng)然,躲開(kāi)Tomcat進(jìn)程對(duì)提高并發(fā)和提高穩(wěn)定性肯定是有好處的。大家都知道,httpd可以通過(guò)mod_jk來(lái)和Tomcat服務(wù)器集成,而lighttpd沒(méi)有mod_jk,但是可以通過(guò)mod_proxy實(shí)現(xiàn)相同的功能,也就是讓lighttpd做前端服務(wù)器,把動(dòng)態(tài)請(qǐng)求分別發(fā)送到后端的Tomcat,并實(shí)現(xiàn)負(fù)載均衡和緩存。

          上面的測(cè)試還有一個(gè)問(wèn)題,那就是純代碼的測(cè)試,而在實(shí)際應(yīng)用中,除了運(yùn)行動(dòng)態(tài)代碼,還有數(shù)據(jù)庫(kù)操作,數(shù)據(jù)庫(kù)操作也是非常費(fèi)時(shí)間的。我在想,應(yīng)該再寫(xiě)一個(gè)測(cè)試代碼,就把上面生成的這1001個(gè)字符串寫(xiě)入數(shù)據(jù)庫(kù)再取出,看看運(yùn)行速度如何。

          C++雖然運(yùn)行速度快,但是用來(lái)寫(xiě)Web應(yīng)用還是比較難的,我讀了FastCGI develep kit的源代碼,它只實(shí)現(xiàn)了很底層的功能:讀入環(huán)境變量,標(biāo)準(zhǔn)輸入輸出。很顯然,它對(duì)多字節(jié)字符支持是沒(méi)有的,所有對(duì)于網(wǎng)絡(luò)上千奇百怪的字符編碼,我們普通程序員是沒(méi)有辦法處理的。在Web開(kāi)發(fā)領(lǐng)域,更缺少基于C++的頁(yè)面模板引擎、MVC引擎、IOC引擎、ORM引擎、SOA引擎,等等。如果有哪個(gè)高手立志于C++ Web開(kāi)發(fā),寫(xiě)一個(gè)基于C++的超級(jí)牛B的框架,說(shuō)不定可以創(chuàng)立一番大事業(yè)。

          PHP應(yīng)該是個(gè)不錯(cuò)的選擇,因?yàn)閘ighttpd的作者還有另外一個(gè)作品,那就是XCache,是用來(lái)緩存PHP的字節(jié)碼的,據(jù)說(shuō)可以提高PHP的執(zhí)行速度3-5倍。這么說(shuō)來(lái),PHP甚至可以達(dá)到和C++相同的性能。PHP也有不錯(cuò)的開(kāi)發(fā)框架Zend,PHP有豐富的庫(kù)可供使用。PHP是動(dòng)態(tài)語(yǔ)言,寫(xiě)起代碼來(lái)沒(méi)有Java死板??磥?lái)是不錯(cuò)的選擇。

          Java也不錯(cuò),不過(guò)目前Java領(lǐng)域的應(yīng)用服務(wù)器都很龐大,而且大部分都是基于Java語(yǔ)言開(kāi)發(fā)出來(lái)的,比起C++開(kāi)發(fā)的lihgttpd和nginx,性能自然是要差一點(diǎn)點(diǎn)。不過(guò)對(duì)于企業(yè)開(kāi)發(fā),Java依然是利器,正是因?yàn)閼?yīng)用服務(wù)器的存在,讓我們少考慮很多底層的細(xì)節(jié),讓我們很方便開(kāi)發(fā)分布式的應(yīng)用,穩(wěn)定的企業(yè)級(jí)應(yīng)用。Java的庫(kù)和框架那也是如漫天繁星、數(shù)之不盡的。

          總之,具體怎么選擇,還是要看大家的,我已經(jīng)有點(diǎn)迷茫了。

          評(píng)論

          # re: Web 2.0,決戰(zhàn)效率之巔  回復(fù)  更多評(píng)論   

          2009-04-18 22:56 by SearchFull
          怎么沒(méi)有寫(xiě)完呢?

          # re: Web 2.0,決戰(zhàn)效率之巔  回復(fù)  更多評(píng)論   

          2009-04-19 13:24 by fireflyc
          這樣不公平吧?
          java有NIO的。你把tomcat的NIO開(kāi)啟看看是效果如何的。我想你會(huì)驚訝的發(fā)現(xiàn)原來(lái)“IOCP、epoll、kqueue”可以不依賴(lài)操作系統(tǒng)的——Java的NIO。

          # re: Web 2.0,決戰(zhàn)效率之巔  回復(fù)  更多評(píng)論   

          2009-04-20 09:15 by r
          你java寫(xiě)的不好,用StringBuilder

          # re: Web 2.0,決戰(zhàn)效率之巔[未登錄](méi)  回復(fù)  更多評(píng)論   

          2009-04-20 10:05 by 海邊沫沫
          用StringBuffer就不公平了,因?yàn)镻HP中也是用的字符串連接,大量創(chuàng)建消毀字符串對(duì)象是肯定的。只有c++最占便宜

          # re: Web 2.0時(shí)代,決戰(zhàn)效率之巔  回復(fù)  更多評(píng)論   

          2009-04-20 12:29 by 海邊沫沫
          最新測(cè)試結(jié)果:
          Tomcat開(kāi)啟NIO后:28.33req/s
          JSP代碼改用StringBuffer后:193.05req/s

          根據(jù)樓上兩位的回復(fù),我先是對(duì)開(kāi)啟了Tomcat的NIO,結(jié)果發(fā)現(xiàn)性能基本沒(méi)有改變,理論上講NIO應(yīng)該不可能一點(diǎn)性能提升都沒(méi)有的,有可能是Tomcat默認(rèn)就已經(jīng)開(kāi)啟了NIO,不需要顯式配置。

          然后我優(yōu)化了一下代碼,該用了StringBuffer,結(jié)果不得了,性能提升了5-6倍。和C++的性能以經(jīng)很接近了。由此可見(jiàn),在Java中創(chuàng)建對(duì)象開(kāi)銷(xiāo)還是很高的。另外,我把Random rand = new Random()換了個(gè)地方,這樣每運(yùn)行一次JSP只需要?jiǎng)?chuàng)建一個(gè)Random對(duì)象。

          請(qǐng)看截圖,上面一張是開(kāi)啟NIO后的結(jié)果,下面一張是優(yōu)化代碼后的結(jié)果。






          下面是優(yōu)化后的代碼:

          <%@ page language="java" contentType="text/html; charset=UTF-8"
          pageEncoding="UTF-8"%>
          <%@ page import="java.util.Random" %>
          <%@ page import="java.util.Arrays" %>
          <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
          <html>
          <head>
          <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
          <title>Insert title here</title>
          </head>
          <body>
          <%!
          Random rand = new Random();
          public String make_string ( int word_count,int word_length) {

          char letters[] = "abcdefghijklmnopqrstuvwxyz".toCharArray();
          StringBuffer temp_string = new StringBuffer();
          for (int i = 0; i < word_count; i++) {
          StringBuffer temp_word = new StringBuffer();
          for (int j = 0; j < word_length; j++) {
          int index = rand.nextInt(26);
          temp_word.append(letters[index]);
          }
          temp_string.append(" ");
          temp_string.append(temp_word);
          }
          return temp_string.toString();
          }
          %>
          <%
          String[] strings = new String[1001];
          strings[0] = make_string(1000,rand.nextInt(10)+1);
          for(int i=1; i<1001; i++){
          strings[i] = make_string(10,rand.nextInt(10)+1);
          }
          Arrays.sort(strings);

          for(int i=0; i<1001; i++){
          %>
          <%=strings[i]%><br><br>
          <%
          }

          %>
          </body>
          </html>

          # re: Web 2.0時(shí)代,決戰(zhàn)效率之巔  回復(fù)  更多評(píng)論   

          2009-04-20 18:10 by 海邊沫沫
          下面再增加一個(gè)比較項(xiàng)目,那就是對(duì)靜態(tài)文件的響應(yīng)速度。我把前面用PHP生成的頁(yè)面保存下來(lái),作為test.html,文件大小是80多k,然后使用
          ab -c 1000 -n 10000 http://localhost/test.html
          ab -c 1000 -n 10000 http://localhost:8080/test.html
          進(jìn)行測(cè)試。

          結(jié)果:
          Apache httpd:3276 req/s
          lighttpd:5633 req/s
          nginx: 6080 req/s
          Tomcat:1015 req/s

          結(jié)果表明,Tomcat只有nginx的六分之一,而且Tomcat的Failed Request字段的值太高,其余三個(gè)服務(wù)器該字段的值都是0,說(shuō)明Tomcat面對(duì)大量并發(fā)連接時(shí)還不夠穩(wěn)定。所以,使用lighttpd或nginx做Tomcat的反向代理,并進(jìn)行緩存,應(yīng)該可以獲得不錯(cuò)的性能。

          下面上圖:






          # re: Web 2.0時(shí)代,決戰(zhàn)效率之巔  回復(fù)  更多評(píng)論   

          2009-05-30 14:40 by 虎嘯龍吟
          樓主強(qiáng)啊,什么都會(huì)啊

          # re: Web 2.0時(shí)代,決戰(zhàn)效率之巔  回復(fù)  更多評(píng)論   

          2009-06-24 17:58 by ycmhn
          這種簡(jiǎn)單并且cpu密集的任務(wù)肯定是java比php占優(yōu)勢(shì)
          因?yàn)楫吘故前刖幾g語(yǔ)言
          但是復(fù)雜的任務(wù)php最大的好處是擴(kuò)展多~而且很容易用c語(yǔ)言寫(xiě)擴(kuò)展,
          如果把你這個(gè)寫(xiě)成c擴(kuò)展的話(huà)~~~嘿嘿 那就難說(shuō)了~
          java。。。我看了幾年都很少看到用C寫(xiě)擴(kuò)展的,因?yàn)閖ava對(duì)自己速度比較自信,且編寫(xiě)擴(kuò)展比較繁雜
          上面說(shuō)看到nio會(huì)很驚訝的同學(xué),,,可能是對(duì)別的語(yǔ)言了解比較少~其實(shí)說(shuō)的就是一個(gè)跨平臺(tái)問(wèn)題~
          以前我也為java宣稱(chēng)的跨平臺(tái)激動(dòng)過(guò)~可是呢~名不符實(shí)~不如很多腳本好

          # re: Web 2.0時(shí)代,決戰(zhàn)效率之巔  回復(fù)  更多評(píng)論   

          2009-06-30 11:29 by aDuan
          web 2.0
          nginx + php + mysql.
          主站蜘蛛池模板: 腾冲县| 肃南| 平乐县| 乐平市| 枣庄市| 瑞昌市| 博客| 曲周县| 罗田县| 哈密市| 临泉县| 扎囊县| 新余市| 临洮县| 陇西县| 哈密市| 石景山区| 遂平县| 昆明市| 前郭尔| 顺义区| 嘉峪关市| 恭城| 开阳县| 习水县| 南丰县| 梅河口市| 彰化县| 昭通市| 睢宁县| 怀来县| 灵武市| 明光市| 湾仔区| 增城市| 大港区| 望江县| 安阳市| 千阳县| 兴隆县| 潞城市|