(57)【要約】      （修正有）【課題】ウェブアプリケーションサーバの動作のパフォーマンスを向上させる。【解決手段】ＨＴＴＰリクエストを受け付けてＨＴＭＬファイルを生成するサーバであって、前記ＨＴＭＬファイルを生成するアプリケーション実行部１２０と、前記ＨＴＭＬファイルを含む、当該ＨＴＴＰリクエストに対するＨＴＴＰレスポンスを送信するＨＴＴＰサーバ１１０とを備え、前記アプリケーション実行部１２０は、前記ＨＴＭＬファイルを生成する際にスクリプトを実行し、当該スクリプトの命令コードが文字列を処理する命令であった場合、前記文字列について出現回数を算出し、前記出現回数が既定値以上の文字列を文字列ファイルとして記憶装置１４０に保持する手段を有し、前記アプリケーション実行部１２０は、さらに前記文字列が、前記記憶した文字列と一致した場合に、当該参照情報の指す文字列ファイルを前記ＨＴＭＬファイルと共に送信する手段を有するサーバ１００。【選択図】図１
2010250653.tif 000002
【特許請求の範囲】
【請求項１】
ＨＴＴＰリクエストを受け付けてＨＴＭＬファイルを生成するサーバであって、
前記ＨＴＴＰリクエストに基づいて前記ＨＴＭＬファイルを生成するアプリケーション実行部と、
前記ＨＴＴＰリクエストを受信し、前記アプリケーション実行部により生成された前記ＨＴＭＬファイルを含む、当該ＨＴＴＰリクエストに対するＨＴＴＰレスポンスを送信するＨＴＴＰサーバとを備え、
前記アプリケーション実行部は、前記ＨＴＭＬファイルを生成する際にスクリプトを実行し、当該スクリプトの命令コードが文字列を処理する命令であった場合、前記文字列について出現回数を算出し、前記出現回数が既定値以上の文字列を文字列ファイルとして記憶装置に保持する手段を有し、
前記アプリケーション実行部は、さらに前記ＨＴＭＬファイルを生成する際にスクリプトを実行し、当該スクリプトの命令コードが文字列を処理する命令であり、かつ前記文字列が、前記記憶した文字列と一致した場合に、前記文字列を前記文字列ファイルへの参照情報に置換して、当該ＨＴＭＬファイルを生成する手段と有し、
前記ＨＴＴＰサーバは、前記アプリケーション実行部により生成された前記ＨＴＭＬファイルに、前記文字列ファイルへの参照情報がある場合に、当該参照情報の指す文字列ファイルを前記ＨＴＭＬファイルと共に送信する手段
を有するサーバ。
【請求項２】
前記文字列を処理する命令コードが連続して存在した場合に、連結した文字列を１つの文字列ファイルとして記憶する、請求項１記載のサーバ。
【請求項３】
前記出現回数が、命令コードの引数に代入された文字列長、メモリコピーにかかる時間、システムコールを実行する時間、実行時の文字列比較に要する、文字列の出現回数に基づく関数の値である、請求項１記載にサーバ。
【請求項４】
前記関数の値（Score）が次式による、請求項３記載のサーバ。
Score = (MemoryCopy(size)- SystemCall - Compare(size)) * Frequency) / size
size: 命令コードの引数に代入された文字列長（バイト数）
MemoryCopy(size) : メモリコピーにかかる時間（秒）
SystemCall: システムコールを実行する時間（秒）
Compare: 実行時の文字列比較に要する時間（秒） 
Frequency: 文字列の出現回数
【請求項５】
ＨＴＴＰリクエストを受け付けてＨＴＭＬファイルを生成するサーバにおいて、ＨＴＴＰレスポンスを送信する方法であって、
前記ＨＴＭＬファイルを生成する際にスクリプトを実行し、当該スクリプトの命令コードが文字列を処理する命令であった場合、前記文字列について出現回数を算出し、前記出現回数が既定値以上の文字列を文字列ファイルとして記憶装置に保持するステップと、
前記ＨＴＭＬファイルを生成する際にスクリプトを実行し、当該スクリプトの命令コードが文字列を処理する命令であり、かつ前記文字列が、前記記憶した文字列と一致した場合に、前記文字列を前記文字列ファイルへの参照情報に置換して、当該ＨＴＭＬファイルを生成するステップと、
生成された前記ＨＴＭＬファイルに、前記文字列ファイルへの参照情報がある場合に、当該参照情報の指す文字列ファイルを前記ＨＴＭＬファイルと共に送信するステップ
を有する方法。
【請求項６】
ＨＴＴＰリクエストを受け付けてＨＴＭＬファイルを生成するサーバにおいて、ＨＴＴＰレスポンスを送信するためのプログラムであって、前記プログラムが前記サーバに、
前記ＨＴＭＬファイルを生成する際にスクリプトを実行し、当該スクリプトの命令コードが文字列を処理する命令であった場合、前記文字列について出現回数を算出し、前記出現回数が既定値以上の文字列を文字列ファイルとして記憶装置に保持するステップと、
前記ＨＴＭＬファイルを生成する際にスクリプトを実行し、当該スクリプトの命令コードが文字列を処理する命令であり、かつ前記文字列が、前記記憶した文字列と一致した場合に、前記文字列を前記文字列ファイルへの参照情報に置換して、当該ＨＴＭＬファイルを生成するステップと、
生成された前記ＨＴＭＬファイルに、前記文字列ファイルへの参照情報がある場合に、当該参照情報の指す文字列ファイルを前記ＨＴＭＬファイルと共に送信するステップ
を実行させるプログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、ウェブサーバの高速化技術に関し、特に動的にコンテンツを生成するウェブサーバの高速化に関する。
【背景技術】
【０００２】
ウェブ・アプリケーション・サーバ（以降、ウェブサーバ）への性能要求に対しては、サーバ台数を増やすスケールアウト技術が知られているが、管理コストや消費電力などの問題があるため、単一のウェブの高性能化技術は依然として重要な技術課題となっている。本発明は、ウェブサーバがフロントエンドのHTTPサーバとバックエンドのプログラミング言語処理系（以降、言語処理系）から構成された一般的なウェブサーバ環境の更なる高速化を対象にする。動的なコンテンツ生成を可能にするこれらの構成では、言語処理系が動的な HTML 生成を担当し、HTTPサーバはそれらの生成されたコンテンツをクライアントに HTTP レスポンスメッセージとして返答する役割を果たす。PHP 言語の場合、言語処理系とHTTPサーバは同一のプロセス上では Apache の mod_php、別プロセスの場合には FastCGI で接続する。この２つのコンポーネントをつなぐ手法（SAPI：ServerApplication Programming Interface）として、 FastCGI や mod_php などの手法がある。
【０００３】
SAPI として FastCGI を用いる場合の実装として、例えば、Faster FastCGIと呼ばれる手法がある（例えば、非特許文献１参照）。この手法では、PHP 言語処理系が共有メモリ（/dev/shm）に割り当てたファイルに対して実行結果を書き出し、FastCGI のプロトコル上にはそのファイル名を HTTP のヘッダ（X-LIGHTTTPD-tempfile）として流すことにより、HTTPサーバの FastCGI モジュール（ mod_php ）が、ＯＳ（Operating System）の sendfile システムコールを用いてメッセージを送る。しかしながら言語処理系が生成したコンテンツをHTTPサーバに渡す際のメモリコピーにかかるコストがオーバヘッドとなり、スループットの低下を招くことが知られている。
【０００４】
【非特許文献１】"lighty's lifeFaster FastCGI"、[online]、2006年11月29日、lighty's life、[2008年2月29日検索]、インターネット＜URL : http://blog.lighttpd.net/articles/2006/11/29/faster-fastcgi＞
【発明の開示】
【発明が解決しようとする課題】
【０００５】
上記のようなウェブ・アプリケーション・サーバでは、一般に、クライアント（HTTPクライアント）からのリクエストを受け付け、このリクエストに応じて HTML （HyperText Markup Language）ファイルが生成され、生成されたHTMLファイルがクライアントへ返送されるといった一連の動作が行われる。この場合、HTTPサーバによる処理とアプリケーション実行部による処理とが移行しながら実行されるのに伴い、メモリのユーザ空間（ユーザ・メモリ）とカーネル空間（カーネル・メモリ）との間で、度々メモリコピーが行われる。アプリケーション実行部の動作によっては、記憶装置から必要なデータが読み出され、この読み出されたデータも一緒にコピーされる。
【０００６】
このメモリコピーには一定の処理コストを要す。そのため、冗長なメモリコピーが繰り返されると、ウェブ・アプリケーション・サーバ全体のパフォーマンスの低下を招くこととなる。
【０００７】
本発明は、上記の課題を解決し、メモリコピーによる処理コストを軽減し、ウェブ・アプリケーション・サーバの動作のパフォーマンスを向上させることを目的とする。
【課題を解決するための手段】
【０００８】
上記の目的を達成するため、本発明は、次のようなサーバとして実現される。このサーバは、ＨＴＴＰリクエストを受け付けてＨＴＭＬファイルを生成するサーバであって、前記ＨＴＴＰリクエストに基づいて前記ＨＴＭＬファイルを生成するアプリケーション実行部と、前記ＨＴＴＰリクエストを受信し、前記アプリケーション実行部により生成された前記ＨＴＭＬファイルを含む、当該ＨＴＴＰリクエストに対するＨＴＴＰレスポンスを送信するＨＴＴＰサーバとを備え、前記アプリケーション実行部は、前記ＨＴＭＬファイルを生成する際にスクリプトを実行し、当該スクリプトの命令コードが文字列を処理する命令であった場合、前記文字列について出現回数を算出し、前記出現回数が既定値以上の文字列を文字列ファイルとして記憶装置に保持する手段を有し、前記アプリケーション実行部は、さらに前記ＨＴＭＬファイルを生成する際にスクリプトを実行し、当該スクリプトの命令コードが文字列を処理する命令であり、かつ前記文字列が、前記記憶した文字列と一致した場合に、前記文字列を前記文字列ファイルへの参照情報に置換して、当該ＨＴＭＬファイルを生成する手段と有し、前記ＨＴＴＰサーバは、前記アプリケーション実行部により生成された前記ＨＴＭＬファイルに、前記文字列ファイルへの参照情報がある場合に、当該参照情報の指す文字列ファイルを前記ＨＴＭＬファイルと共に送信する。
【０００９】
また、前記文字列を処理する命令コードが連続して存在した場合に、連結した文字列を１つの文字列ファイルとして記憶する構成としても良い。
【００１０】
また、前記出現回数が、命令コードの引数に代入された文字列長、メモリコピーにかかる時間、システムコールを実行する時間、実行時の文字列比較に要する、文字列の出現回数に基づく関数の値であるようにしても良い。
【００１１】
好ましくは、前記関数の値（Score）を次式によって計算するようにする。
Score = (MemoryCopy(size)- SystemCall - Compare(size)) * Frequency) / size
size: 命令コードの引数に代入された文字列長（バイト数）
MemoryCopy(size) : メモリコピーにかかる時間（秒）
SystemCall: システムコールを実行する時間（秒）
Compare: 実行時の文字列比較に要する時間（秒） 
Frequency: 文字列の出現回数
【００１２】
さらに本発明は、ＨＴＴＰリクエストを受け付けてＨＴＭＬファイルを生成するサーバにおいて、ＨＴＴＰレスポンスを送信する方法であって、前記ＨＴＭＬファイルを生成する際にスクリプトを実行し、当該スクリプトの命令コードが文字列を処理する命令であった場合、前記文字列について出現回数を算出し、前記出現回数が既定値以上の文字列を文字列ファイルとして記憶装置に保持するステップと、前記ＨＴＭＬファイルを生成する際にスクリプトを実行し、当該スクリプトの命令コードが文字列を処理する命令であり、かつ前記文字列が、前記記憶した文字列と一致した場合に、前記文字列を前記文字列ファイルへの参照情報に置換して、当該ＨＴＭＬファイルを生成するステップと、生成された前記ＨＴＭＬファイルに、前記文字列ファイルへの参照情報がある場合に、当該参照情報の指す文字列ファイルを前記ＨＴＭＬファイルと共に送信するステップを有する方法を提供することができる。
【００１３】
さらに本発明は、ＨＴＴＰリクエストを受け付けてＨＴＭＬファイルを生成するサーバにおいて、ＨＴＴＰレスポンスを送信するためのプログラムであって、前記プログラムが前記サーバに、前記ＨＴＭＬファイルを生成する際にスクリプトを実行し、当該スクリプトの命令コードが文字列を処理する命令であった場合、前記文字列について出現回数を算出し、前記出現回数が既定値以上の文字列を文字列ファイルとして記憶装置に保持するステップと、前記ＨＴＭＬファイルを生成する際にスクリプトを実行し、当該スクリプトの命令コードが文字列を処理する命令であり、かつ前記文字列が、前記記憶した文字列と一致した場合に、前記文字列を前記文字列ファイルへの参照情報に置換して、当該ＨＴＭＬファイルを生成するステップと、生成された前記ＨＴＭＬファイルに、前記文字列ファイルへの参照情報がある場合に、当該参照情報の指す文字列ファイルを前記ＨＴＭＬファイルと共に送信するステップを実行させるプログラムを提供することができる。
【発明の効果】
【００１４】
以上のように構成された本発明によれば、HTMLファイルを動的に生成する際に、出現頻度の高い文字列をファイルとして記憶し、これをHTTPリクエストに対する応答に利用することにより、メモリコピーによる処理コストを軽減し、ウェブ・アプリケーション・サーバの動作のパフォーマンスを向上させることができる。
【発明を実施するための最良の形態】
【００１５】
以下、添付図面を参照して、本発明の実施形態について詳細に説明する。
＜システム構成＞
図１は、本実施形態のウェブ・アプリケーション・サーバの機能構成を示す図である。
図１に示すウェブ・アプリケーション・サーバ１００は、パーソナルコンピュータ等のコンピュータにより実現され、HTTPサーバ１１０と、アプリケーション実行部１２０と、OS実行部１３０と、記憶装置１４０とを備える。また、ネットワークを介してクライアント２００と接続されている。
【００１６】
本実施形態では、アプリケーション実行部１２０として PHP （PHP: HypertextPreprocessor）言語処理系が用いられるものとする。また、HTTPサーバ１１０とアプリケーション実行部１２０との間の通信チャネル（ＳＡＰＩ）としては、 FastCGI が用いられるものとする。図１に示すように、アプリケーション実行部１２０は、通常の PHP ランタイム・ライブラリ（以下、単にランタイムと記す）１２１と、本実施形態により拡張される機能を担う拡張ライブラリ１２２とを備える。
【００１７】
図２は、本実施形態が適用されるコンピュータのハードウェア構成例を示す図である。
図２に示すコンピュータ１０は、演算手段であるＣＰＵ（Central Processing Unit）１０ａと、記憶手段であるメイン・メモリ１０ｃおよび磁気ディスク装置（ＨＤＤ：Hard Disk Drive）１０ｇを備える。メイン・メモリ１０ｃのサイズに十分なサイズがあればメイン・メモリの一部を RAM DISK として使用する。本発明における文字列ファイルをこの RAM DISK に記憶することもできる。また、ネットワークを介して外部装置に接続するためのネットワーク・インタフェース・カード１０ｆと、表示出力を行うためのビデオ・カード１０ｄおよび表示装置１０ｊと、音声出力を行うための音声機構１０ｈとを備える。さらに、キーボードやマウス等の入力デバイス１０ｉを備える。
【００１８】
図２に示すように、メイン・メモリ１０ｃおよびビデオ・カード１０ｄは、システム・コントローラ１０ｂを介してＣＰＵ１０ａに接続されている。また、ネットワーク・インタフェース・カード１０ｆ、磁気ディスク装置１０ｇ、音声機構１０ｈおよび入力デバイス１０ｉは、Ｉ／Ｏコントローラ１０ｅを介してシステム・コントローラ１０ｂと接続されている。各構成要素は、システム・バスや入出力バス等の各種のバスによって接続される。例えば、ＣＰＵ１０ａとメイン・メモリ１０ｃの間は、システム・バスやメモリ・バスにより接続される。また、ＣＰＵ１０ａと磁気ディスク装置１０ｇ、ネットワーク・インタフェース・カード１０ｆ、ビデオ・カード１０ｄ、音声機構１０ｈ、入力デバイス１０ｉ等との間は、ＰＣＩ（Peripheral Components Interconnect）、ＰＣＩ  Ｅｘｐｒｅｓｓ、シリアルＡＴＡ（AT Attachment）、ＵＳＢ（UniversalSerial Bus）、ＡＧＰ（AcceleratedGraphics Port）等の入出力バスにより接続される。
【００１９】
なお、図２は、本実施形態が適用されるのに好適なコンピュータのハードウェア構成を例示するに過ぎず、実際の各サーバが図示の構成に限定されないことは言うまでもない。例えば、ビデオ・カード１０ｄを設ける代わりに、ビデオメモリのみを搭載し、ＣＰＵ１０ａにてイメージ・データを処理する構成としても良い。また、音声機構１０ｈを独立した構成とせず、システム・コントローラ１０ｂやＩ／Ｏコントローラ１０ｅを構成するチップセットの機能として備えるようにしても良い。また、補助記憶装置として磁気ディスク装置１０ｇの他に、各種の光学ディスクやフレキシブル・ディスクをメディアとするドライブを設けても良い。表示装置１０ｊとしては、主として液晶ディスプレイが用いられるが、その他、任意の方式のディスプレイを用いて良い。
【００２０】
図１に示したウェブ・アプリケーション・サーバ１００において、HTTPサーバ１１０、アプリケーション実行部１２０およびOS実行部１３０の各機能は、例えば図２に示したコンピュータにおいて、メイン・メモリ１０ｃに読み込まれたプログラムをＣＰＵ１０ａが実行することにより実現される。記憶装置１４０は、磁気ディスク装置１０ｇにより実現される。また、アプリケーションが使用するユーザ・メモリおよびＯＳが使用するカーネル・メモリは、メイン・メモリ１０ｃにより実現される。
【００２１】
図１において、HTTPサーバ１１０は、OS上で動作し、ネットワークを介して HTTP 通信を行うためのサーバであり、クライアント２００からHTTPリクエストを受け付けてアプリケーション実行部１２０に渡す。そして、アプリケーション実行部１２０から受け取った処理結果を HTTP レスポンスとしてクライアント２００に返送する。クライアント２００から受け付けたHTTPリクエストは、まずカーネル・メモリのソケット・バッファに格納され、HTTPサーバ１１０のアプリケーションによって使用されるユーザ・メモリに読み込まれる。反対に、 HTTP レスポンスが送信される際は、カーネル・メモリのソケット・バッファに一旦格納された後、クライアント２００へ送信される。また、本実施形態のHTTPサーバ１１０は、ユーザ・メモリとカーネル・メモリとの間でのメモリコピーの負荷を軽減するため、アプリケーション実行部１２０に付与された拡張機能に応じた処理を実行する。この処理の詳細については、後述する。
【００２２】
アプリケーション実行部１２０は、OS上で動作する PHP 言語処理系であり、HTTPサーバ１１０により受け付けられたHTTPリクエストに応じて、ランタイム１２１および拡張ライブラリ１２２を用いてHTMLファイルを動的に生成する。ウェブ・アプリケーション・サーバ１００には、HTTPリクエストに対応する具体的なHTMLファイルの元となるHTMLファイルが保持されている。この元となるHTMLファイルには、HTTPリクエストに応じて実行される PHP スクリプトが記述されている。この PHP スクリプトがアプリケーション実行部１２０で実行されることによりオブジェクト（ウェブ・オブジェクト）が生成される。そして、生成されたオブジェクトが元となるHTMLファイルに埋め込まれることにより、HTTPリクエストに対応する具体的なHTMLファイルが動的に生成されることとなる。
【００２３】
図１に示したように、このアプリケーション実行部１２０は、ランタイム１２１と拡張ライブラリ１２２とを備える。ランタイム１２１は、 PHP スクリプトを実行するための通常のランタイム・ライブラリである。本実施形態のアプリケーション実行部１２０では、メモリコピーの負荷を軽減するための機能もランタイム１２１により提供される。拡張ライブラリ１２２（ PHP ではｅｘｔｅｎｓｉｏｎと呼ばれる）は、本実施形態によるメモリコピーの負荷を軽減するための仕組みにおいて用いられる補助的な機能を提供する。これらのライブラリの機能およびこれらのライブラリを用いたアプリケーション実行部１２０の動作の詳細については、後述する。
【００２４】
OS実行部１３０は、OSを実行し、ウェブ・アプリケーション・サーバ１００の基本機能を提供する。HTTPサーバ１１０およびアプリケーション実行部１２０は、このOS上で動作する。なお、図１においては、便宜的にHTTPサーバ１１０およびアプリケーション実行部１２０には共通のOS実行部１３０が記載されているが、HTTPサーバ１１０およびアプリケーション実行部１２０が異なるOS上で動作する形態でも構わない。つまりHTTPサーバとアプリケーションサーバが FastCGIプロトコルで通信していれば、両サーバが異なるマシンで稼動していても構わない。
【００２５】
記憶装置１４０は、アプリケーション実行部１２０により動的に生成される具体的なHTMLファイルの元となるHTMLファイルを保持する。また、記憶装置１４０は、所定のデータを保持する。このデータは、アプリケーション実行部１２０により生成されたHTMLファイルに書き出される。本実施形態では、アプリケーション実行部１２０の拡張ライブラリ１２２により提供された機能を用いて、 HTTP レスポンスが送信される際に、HTTPサーバ１１０によって記憶装置１４０からデータが読み出され、HTMLファイルに書き出される。
【００２６】
上記のように構成されるウェブ・アプリケーション・サーバ１００において、HTTPサーバ１１０では、データを受信した際に、カーネル・メモリのソケット・バッファからユーザ・メモリへメモリコピーが行われる。また、データを送信する際に、ユーザ・メモリからカーネル・メモリのソケット・バッファへメモリコピーが行われる。さらに、HTTPサーバ１１０とアプリケーション実行部１２０との間でのデータのやり取りは、ＯＳが管理するカーネル・メモリを介して行われる。そのため、一方から他方へデータが渡される度に、ユーザ・メモリとカーネル・メモリとの間でメモリコピーが２回行われる。
【００２７】
本実施形態は、このメモリコピーにおける負荷を軽減する仕組みを実現するため、HTMLファイルを構成するオブジェクトに使用頻度の高い文字列が存在する場合、その文字列を含む文字列ファイルへの参照情報（ポインタ）で置換することによりて処理を高速化する。例えば、ＰＨＰスクリプトで記述される、変数 $x によく使用される非常に長い文字列が使用されている場合、それをそのまま展開せずに、予め RAMDISK 等に記憶された文字列ファイルへの参照情報（ＵＲＩ）を指定するように書き換える。この実装は、アプリケーション・プログラムからは透過であり、通常の文字列オブジェクトと同じセマンティクスを保持している。この文字列ファイルにおけるファイルの中身の取得は、ＨＴＴＰサーバ１１０により実行される。アプリケーション実行部１２０は、文字列ファイルの処理をＨＴＴＰサーバ１１０に依頼するために、アプリケーション実行部１２０からＨＴＴＰサーバ１１０へ送られる FastCGI プロトコルのメッセージのヘッダに特別なヘッダ情報を追加する。このヘッダ情報を、「X-FileString ヘッダ」と呼ぶ。X-FileStringヘッダには、 FastCGI メッセージのボディ部に記載されるファイル名の位置（ファイル名の先頭文字の位置を示すオフセット値およびファイル名の長さ）が記述される。ＨＴＴＰサーバ１１０は、このX-FileString ヘッダに基づいてファイルを特定し、例えばＯＳのｓｅｎｄｆｉｌｅシステムコールを用いて、このファイルをクライアント２００へ送信する。
【００２８】
＜プロファイリング＞
使用頻度情報はプロファイリングにより取得する。文字列処理を行う命令コードにおける引数として文字列オブジェクトを扱う変数が指定されている場合、その文字列について統計情報を取得する。統計情報とはその文字列の長さ、出現回数などである。文字列をHTTPサーバと言語処理系のアプリケーションサーバとの間でやり取りすると数回メモリコピーが発生し、長い文字列を何回も処理するとウェブサーバ全体としてのパフォーマンスに影響を与える。より具体的な PHP スクリプトの例を挙げて、プロファイリングのデータ処理の手順を説明する。図３に PHP スクリプトの一例を示す。このPHP スクリプトはウェブ・アプリケーションにおいてよく用いられるパターンであり、殆ど固定されたメッセージを echo（標準出力に文字列を表示する） 命令で表示させるものである。図３の例では３つのメッセージが表示されている。アプリケーション実行部１２０は、まず PHP スクリプトをパースし、命令コードに翻訳する。そして翻訳した命令コードを実行する。このとき echo に相当する命令コードを実行する際、引数の変数が文字列オブジェクトか否かを判定する。文字列オブジェクトであった場合には、その文字列を記録し統計を取る。例えば echo 命令の引数が変数 $x であった場合、変数 $x の値として  aaaa，bbbb，cccc，dddd（これは便宜上短いが実際には数KBの長さがある）という４つの文字列が使用されていることを記録し、その中でbbbbという文字列の使用頻度が既定値より高い場合には、それを特定の名前で文字列ファイルとして記憶する。既定値としては使用回数、４文字中の使用される割合（例えば５０％以上）などの指標を用いる。プロファイリングを行うかどうかはメモリコピーがＣＰＵの使用率に占める割合がある閾値（例えば５％）を超える場合に行うとか、時間指定で８：００から１２：００までに行うなどのバリエーションが考えられる。上記の例では簡便のため文字列ファイルを作成する基準として使用頻度を用いたがその他のパラメータを考慮した評価関数を適用することも可能である。これについての詳細を次に記載する。
【００２９】
＜評価関数の使用＞
アプリケーション実行部１２０の言語処理系が各 echo 命令文を処理する際に用いる評価関数を用いる場合を説明する。評価関数で得られるスコアが既定の値以上の文字列について文字列ファイルが作成され、最終的にこの文字列ファイルがＯＳのシステムコールである sendfile を用いてユーザに送信されることになる。
Score = (MemoryCopy(size)- SystemCall - Compare(size)) * Frequency) / size
ここで
Score: スコア
size: 命令コード（echo）の引数に代入された文字列長（バイト数）
MemoryCopy(size) : メモリコピー (memcpy 関数)にかかるコスト（時間：秒）
SystemCall: システムコール（sendfile）を実行するコスト（時間：秒）
Compare: 実行時の文字列比較に要するコスト（時間：秒）
Frequency: 命令コード（echo）における同一文字列の出現回数
である。
【００３０】
評価値 Score の分子がメモリコピーにかかるコストが大きければ、sendfile システムコールに変換する効果が高いので、値が大きくなる。ただし、システムコールのオーバーヘッドも考慮しなければならないので、定数値 SystemCall 分が引かれている。つまり、もし、size が小さくメモリコピーのコストがシステムコールのコストよりも小さい場合には、スコアはマイナスになるので、その場合には Score は 0 とする。また、Frequency は、その echo がどれだけを実行中に頻繁に実行されるかを表しており、頻度が高くなればなるほどスコアは高くなる。式中で、size で割る理由は、echo の引数が大きければ大きいほど、メモリを圧迫するためである。つまりメモリフットプリントと処理速度のトレードオフを考慮するためである。Compare 関数は実行時の文字列比較のコストであるが、文字列比較コストは、ユーザー空間とカーネル空間の間のメモリコピーのコスト及びコンテキストスイッチのコストと比較すると小さい。例えば FastCGI の場合には PHP 言語処理系からウェブサーバに渡るまでに２回発生する。なお文字列を記憶する場所としては速度の点でメモリディスク（RAM DISK）が好ましいが必須条件ではない。
【００３１】
＜ echo 命令文の統合＞
通常のアプリケーションでは、echo 命令文が複数回実行されることが普通である。たとえば以下の PHP スクリプトで
<?php echo $x;echo $y; echo $z; ?>
変数 $x に aaaa, 変数 $y に bbbb, 変数 $z に cccc が入っていた場合を仮定する。各変数の文字列長は短いとしても、もし、echo $x . $y . $z というように統合した場合には、文字列長は長くなり、sendfile システムコールに置換する効果が現れる。よって、本発明では、以下の手法を用いて、これらの統合を実現する。最適化を施す echo 文の統合条件は echo が２回以上連続して実行されることが条件である。連続して echo が実行された場合には、連続して現れるパターンを記録する。たとえばx?, y?, z? を文字列とした場合、各変数が以下のように表されていると仮定する。
$x = (x1, x2,x3)
$y = (y1, y2,y3)
$z = (z1, z2,z3) 
ここでプロファイリングにより、($x, $y, $z) = (x1, y2, z3) という文字列の組み合わせがほとんどであるという統計情報が得られたとすると、(x1, y2, z3) の文字列を文字列ファイルに落とし、３つの echo 文を統合する。実行時には、$x,$y, $z の変数が (x1, y2, z3) の文字列かどうかを判定し、もしその場合には、あらかじめ生成した文字列ファイルを用いてそのファイルを sendfile し、そうでない場合には通常通り実行する。この echo 命令文の統合手法により、評価関数で単独の評価値Scoreが低いと判断された場合でも、統合することにより大きな効果を出すことができるようになる。また、複数のシステムコールのオーバヘッドを排除することもできる。
【００３２】
＜プロファイリングの結果を用いた実行時処理＞
プロファイル終了後、 echo命令の引数が文字列変数であり、その値が文字列ファイルとして記憶した文字列と一致するかどうかを比較する。もし同一の場合には、その文字列を書き出すのではなく、プロファイリングによって予め生成している文字列ファイルへの参照情報（ポインタ）で置き換える。より詳細には、まず文字列ファイルの中身の取得は、HTTPサーバ１１０により実行される。アプリケーション実行部１２０は、文字列オブジェクトの処理をHTTPサーバ１１０に依頼するために、アプリケーション実行部１２０からHTTPサーバ１１０へ送られる FastCGI プロトコルのメッセージのヘッダに特別なヘッダ情報を追加する。このヘッダ情報を、「X-FileStringヘッダ」と呼ぶ。X-FileStringヘッダには FastCGI メッセージのボディ部に記載される文字列ファイル名の位置（文字列ファイル名の先頭文字の位置を示すオフセット値およびファイル名の長さ）が記述される。HTTPサーバ１１０は、このX-FileStringヘッダに基づいて文字列ファイルを特定し、例えばＯＳの sendfile システムコールを用いて、この文字列ファイルをクライアント２００へ送信する。上の例ではプロファイリングとその結果を用いた処理を分けて説明したが、同時に行うことも可能である。プロファイリングを行いつつ、プロファイリングの結果として文字列ファイルが１つでも作成された時点で上記の処理を適用するようにしてもよい。
【００３３】
ここで、具体的な PHP スクリプトの例を挙げて、上記のプロファイリングの結果を用いたデータ処理の手順を説明する。図３に示すような PHP スクリプトが来ると、アプリケーション実行部１２０は、まず、この PHP スクリプトをパースし、命令コードに翻訳する。そして、翻訳した命令コードを実行する。このとき echo に相当する命令コードを実行する際、変数が文字列オブジェクトであればプロファイリングで作成された文字列ファイルに合致するものがあるかどうかチェックする。そして同一の文字列を有する文字列ファイルがあった場合には、文字列オブジェクトを文字列ファイル名の参照情報であるＵＲＩ（例えば/tmp/str_0001.html）に置き換える。また、 FastCGI パケットのヘッダ情報としてX-FileStringを記述し FastCGI パケット中のファイル名の位置を示すオフセット値および長さを指定する。
【００３４】
この後、アプリケーション実行部１２０で生成された FastCGI パケットがHTTPサーバ１１０に送られて処理される。HTTPサーバ１１０は、受け取った FastCGI パケットのヘッダをパースする。そして、X-FileStringヘッダを見つけた場合、HTTPサーバ１１０は、その FastCGI パケットをそのままソケットに流すのではなく sendfile システムコールを用いて、X-FileStringヘッダで指定されたファイルをクライアント２００に返送する。
【００３５】
以上のように、本実施形態によれば、アプリケーション実行部１２０がファイルを取得する際に必要となるメモリコピーが省略され、アプリケーション実行部１２０からHTTPサーバ１１０へ FastCGI パケットが送られる際に通常行われるメモリコピーについてファイルのコピーは行われない。さらに、HTTPサーバ１１０がクライアント２００へ HTTP レスポンスを返送する際にも、ファイルは、ユーザ・メモリを介することなくカーネル・メモリからクライアント２００へ直接送信される。したがって、ファイルのメモリコピーが省略された分、処理コストが軽減され、ウェブ・アプリケーション・サーバ１００の動作のパフォーマンスが向上することとなる。
【００３６】
＜ライブラリにより提供される機能およびアプリケーション実行部の動作＞
次に、ランタイム１２１および拡張ライブラリ１２２により提供される機能と、アプリケーション実行部１２０の動作について詳細に説明する。
アプリケーション実行部１２０は、クライアント２００からのHTTPリクエストを、HTTPサーバ１１０を介して取得し、このHTTPリクエストに応じて HTTP レスポンスとなるHTMLファイルを動的に生成する。この際、アプリケーション実行部１２０は、この HTTP レスポンスの元となるHTMLファイルに記述された PHP スクリプトを、ランタイム１２１および拡張ライブラリ１２２を用いて実行する。
【００３７】
図４は、拡張ライブラリ１２２によるアプリケーション実行部１２０の動作を示すフローチャートである。アプリケーション実行部１２０は、 PHP スクリプトの命令コードを順次取得し、拡張ライブラリ１２２を用いて処理を行う。図４を参照すると、アプリケーション実行部１２０は、まず命令コードによる処理対象が文字列オブジェクトであるかどうかを判断する（Ｓ４０１）。処理対象が文字列オブジェクトか否かは、命令コードの関数等に基づいて判断することができる。具体的に、どの命令コードや関数の場合に処理対象が文字列ファイルであると判断するかについては、予め定義しておけば良い。文字列オブジェクトでなければ、通常の PHP 言語処理系による拡張ライブラリ１２２を用いた処理と同様の処理を必要に応じて行う（Ｓ４０６）。文字列オブジェクトであった場合、プロファイルするかどうかを判定する。この判定はプロファリング処理の終了フラグがセットされていれば実行時処理（Ｓ４０４）に移る。プロファイリング処理の終了フラグがセットされていなければプロファリング処理（Ｓ４０３）に進む。
【００３８】
プロファイリングの処理（Ｓ４０３）と実行時処理（Ｓ４０４）の詳細なフローについては後述する。実行時処理（Ｓ４０４）が終了した場合、またはプロファイリング処理が終了するとランタイムによる処理に移行する（Ｓ４０５）。
【００３９】
＜プロファイリング処理のフロー＞
図５にプロファイリングの詳細なフローチャートを示す。まず命令コードが echo であるか判断する（Ｓ５０１）。echoでなければその命令コードを実行する（Ｓ５０５）。本発明は文字列を表示する命令コードとして echo についての処理を例示しているが、他の文字列処理コードも同様の処理で可能である。次に echo の処理対象が文字列オブジェクトかどうかを判断する（Ｓ５０２）。文字列オブジェクトでなければ次の未処理コードへ移る（Ｓ５０８）。文字列オブジェクトであれば、その文字列を取り出し、同一の文字列が文字列出現テーブルに記憶されているかチェックする。
【００４０】
文字列出現テーブルは図１０に示されるように各変数が過去に取りえた文字列とその出現回数およびその文字列をファイル化した時のファイル名をメモリに記憶したものである。ファイル名があるかないかでファイル化されているかどうかのフラグの役割も兼ねている。
【００４１】
図１０の例では、変数 $x の場合 bbbb という文字列を過去４回取ったことが記録されている。現在の $x が bbbb であった場合には、そのカウンタを１つ増やして５にする。仮に $x の値が xxxx という過去に記憶したことのない文字列であった場合には新しく文字列出現テーブルに xxxx という文字列とそのカウンタ値として１を記録する。そしてカウンタ値がある所定の値（例えば1000）を超えたらこれを文字列を格納したファイルとして記録する。図１０の場合、文字列 cccc は既にファイル化されていることがわかる。例えば $x の文字列として bbbb が 999回 出現したことが記録している場合に、現在の $x が bbbb であった場合には、カウンタは1000 となりファイル化が行われる（Ｓ５０４）。ファイル化された文字列はファイル名がセットされる。また既定値以上のカウンタの増加はしない。作成されたファイルのファイル名は作成された順にシーケンシャル（str_0001,str_0002など）に決定する。もしくはハッシュ関数により文字列の内容から一意に決定される名前で記録しても良い。
【００４２】
文字列のファイル化が終了すると処理は通常の命令コードの処理を行ったのち未処理のコードに進む（Ｓ５０８）。なお特定の条件を満たした場合にプロファイリングの終了を示すフラグをセットする。具体的には文字列出現テーブルの最大サイズを超えた場合、文字列ファイル数の上限に達した場合、文字列を記憶するメモリの上限に達した場合、もしくは指定された時間を越えた場合などにおいてプロファイリングの終了フラグをセットする。さらに精度よくファイル生成を行うには、評価関数の使用についての段落で記載した Score の値を出現回数の代わりに用いる。 
【００４３】
＜プロファイリングの結果を用いた実行時処理のフロー＞
図６に実行時処理の詳細なフローチャートを示す。まず命令コードが echo であるか判断する（Ｓ６０１）。echoでなければその命令コードを実行する（Ｓ６０５）。本発明は文字列を表示する命令コードとしてecho についての処理を例示しているが、他の文字列処理コードも同様の処理で可能である。次に echo の処理対象が文字列オブジェクトかどうかを判断する（Ｓ６０２）。文字列オブジェクトでなければ次の未処理コードへ移る（Ｓ６０８）。
【００４４】
文字列オブジェクトであれば、その文字列を取り出し、同一の文字列が文字列出現テーブルに記憶されているかチェックする。文字列出現テーブルに合致する文字列がない場合は何も処理しない。もし同一の文字列があった場合には、文字列出現テーブルの最後尾を参照し、ファイル名が記載されているかどうかをチェックする。ファイル名が記載されている場合にはその文字列がファイル化されていること示している。その場合は指定された文字列オブジェクトをそのファイルへの参照情報（ＵＲＩ）で置換する。
【００４５】
例えば echo の対象となる変数が $x でその内容が cccc あった場合には、図１０の文字列出現テーブルを参照してそのファイル名が str_0001 ということが分かるので、図９に示すようにファイル化された文字列を参照するように書き換える。なお文字列ファイルが記憶されるディレクトリ情報については予め固定の場所（例えば/tmp/）と決めておく。文字列出現テーブルにファイル名が記載されていない場合にはファイル化されていないので何も処理しない。置換処理が終了すると処理は未処理のコードに移る（Ｓ６０８）。
【００４６】
＜ランタイムの処理＞
図８は、ランタイム１２１によるアプリケーション実行部１２０の動作を示すフローチャートである。図８を参照すると、アプリケーション実行部１２０は、拡張ライブラリ１２２を用いた処理が済んだ命令コードを順次取得する。そして、その命令コードが「 echo 」か否かを判断する（Ｓ８０１）。命令コードが「 echo 」である場合、次にアプリケーション実行部１２０は、処理対象であるオブジェクトが文字列ファイルか否かを判断する（Ｓ８０２）。文字列ファイルと判断したならば、次にアプリケーション実行部１２０は、オブジェクトの値に入っているファイル名を、ＳＡＰＩとして用いられる FastCGI パケットのボディ部分に追加する。また、そのファイル名の位置を示すオフセット値（ｏｆｆｓｅｔ）と長さ（ｌｅｎｇｔｈ）を FastCGI パケットのX-FileStringヘッダに追加する（Ｓ８０３）。このとき、拡張ライブラリ１２２により生成されたハードリンクに関する情報（リンク名、リンク名の長さ）も、 FastCGI パケットのボディ部分およびX-FileStringヘッダに、それぞれ追加される。X-FileStringヘッダのフォーマットは、例えば次のようになる。
X-FileString：オフセット値／ファイル名の長さ／リンク名の長さ
具体例を挙げると、echo$x において$x が文字列ファイル str_0001 への参照情報（ポインタ）に置換された場合、オフセットを０、既定の文字列ファイルディレクトリが/tmp/ の場合、ヘッダ部、ボディ部は以下のようになる。
ヘッダ部
X-FilesString:0/19/23
ボディ部
/tmp/str_0001.html/tmp/str_0001.html-link
【００４７】
一方、ステップ８０２で、処理対象であるオブジェクトが文字列ファイルではない通常の文字列オブジェクトであると判断した場合、次にアプリケーション実行部１２０は、 FastCGI パケットのボディ部分に、文字列の内容を付加する（Ｓ８０４）。
【００４８】
また、ステップ８０１で、取得した命令コードが「 echo 」でない場合、次にアプリケーション実行部１２０は、処理対象であるオブジェクトが文字列ファイルであって、かつ実行する関数が文字列に影響を与えるものか否かを判断する（Ｓ８０５）。ここで、文字列に影響を与える関数とは、例えば、文字列から空白を除去する関数 trim等が該当する。どの関数が文字列に影響を与えるかについては、予め定義しておけば良い。
【００４９】
オブジェクトが文字列ファイルであり、関数が文字列に影響を与える関数である場合、次にアプリケーション実行部１２０は、処理対象であるファイルを読み込み、文字列ファイルを通常の文字列オブジェクトに置き換える（Ｓ８０６）。そして、ステップ８０１で取得した命令コードを実行し、 FastCGI パケットを作成する（Ｓ８０７）。例えば、下記のような PHP スクリプトの場合、実際にファイルをロードして、通常の文字列オブジェクトとして処理を行う。
【００５０】
一方、オブジェクトが文字列ファイルでないか、または関数が文字列に影響を与えない場合、アプリケーション実行部１２０は、そのままステップ８０１で取得した命令コードを実行し、 FastCGI パケットを作成する（Ｓ８０７）。すなわち、オブジェクトが文字列ファイルであっても、関数が文字列に影響を与えない場合は、処理対象のファイルを読み込むことなく、命令コードが実行されることとなる。ステップ８０３、８０４または８０７で FastCGI パケットが作成された後、アプリケーション実行部１２０は、未処理の命令コードが残っているか調べる（Ｓ８０８）。そして、 PHP スクリプトの各命令コードに対して、順次ステップ８０１乃至ステップ８０７の処理が行われる。全ての命令コードに対して処理が済んだならば、アプリケーション実行部１２０は、通信チャネル（ＳＡＰＩ）を介して、作成された FastCGI パケットをHTTPサーバ１１０に渡す（Ｓ８０９）。
【００５１】
＜HTTPサーバの動作＞
次に、上記のようにしてアプリケーション実行部１２０により生成されたHTMLファイルに対するHTTPサーバ１１０の動作について説明する。
HTTPサーバ１１０は、基本的な動作として、受け付けたHTTPリクエストに対する HTTP レスポンスとして、アプリケーション実行部１２０により生成されたHTMLファイルをクライアント２００に返送する。このとき、HTMLファイルにおける PHP スクリプトの命令コードが「 echo 」である場合、オブジェクトで指定されているファイルの中身がHTMLファイルと一緒にクライアント２００へ送信される必要がある。しかし、本実施形態では、上記のように、送信対象のファイルがアプリケーション実行部１２０により読み込まれていないため、HTMLファイルの該当するオブジェクトにはファイルの中身が埋め込まれていない。そこで、HTTPサーバ１１０が、送信対象のファイルを記憶装置１４０から読み出して、HTMLファイルと共にクライアント２００へ送信する。
【００５２】
図７は、HTMLファイルの送信時のHTTPサーバ１１０によるデータ処理の動作を示すフローチャートである。
図７に示すように、HTTPサーバ１１０は、アプリケーション実行部１２０から FastCGIパケットを受信すると（Ｓ７０１）、その FastCGI パケットのヘッダ部にX-FileStringヘッダが含まれているか否かを判断する（Ｓ７０２）。X-FileStringヘッダが含まれている場合は、以下の一連の処理（Ｓ７０３〜７０６）を実行する。
【００５３】
HTTPサーバ１１０は、まず、 FastCGI パケットのX-FileStringヘッダに記述されているファイル名のオフセット値、ファイル名の長さおよびリンク名の長さを取得する（Ｓ７０３）。次に、HTTPサーバ１１０は、 FastCGI パケットのボディ部を先頭から順に着目し、現在位置（初期的には先頭位置）からステップ７０３で取得したオフセット値で表される位置までに記載されたメッセージ・データをソケット・バッファに送る（Ｓ７０４）。
【００５４】
次に、HTTPサーバ１１０は、ステップ７０３で取得したファイル名の長さおよびリンク名の長さに基づいて、 FastCGI パケットのボディ部に記載されたファイル名およびリンク名を取得する。そして、このファイル名またはリンク名で特定されるファイルを、 sendfile システムコールを用いてソケット・バッファに送る（Ｓ７０５）。このとき、HTTPサーバ１１０は、このファイル名およびリンク名とｓｔａｔシステムコールを用い、対象のファイルが更新されていないか確認する。ファイルが更新されていなければ、リンク名により特定されるファイル（アプリケーション実行部１２０が拡張ライブラリ１２２を用いて生成した複製ファイル）をソケット・バッファに送る。この処理では、 sendfile システムコールを用いてファイルが送信されるため、対象のファイルは、記憶装置１４０から読み出されてカーネル・メモリのファイル・バッファに格納された後、ソケット・バッファに直接送られる。すなわち、HTTPサーバ１１０のアプリケーションが使用するユーザ・メモリから、ソケット・バッファが設けられたカーネル・メモリへファイルがコピーされることはない。
【００５５】
この後、 FastCGI パケットのボディ部における現在の着目位置がボディ部の最後に達したか否かを判断する（Ｓ７０６）。ボディ部の最後に達していなければ、ステップ７０３に戻り、ステップ７０３〜７０５の処理を繰り返す。
【００５６】
現在の着目位置がボディ部の最後に達したならば、HTTPサーバ１１０によるデータ処理は終了する。ステップ７０２で、 FastCGI パケットのヘッダ部にX-FileStringヘッダが含まれていないと判断された場合は、何ら特別のデータ処理が行われることなく、 FastCGI パケットのボディ部に記載されているメッセージ・データがソケット・バッファに送られる（Ｓ７０７）。
HTTPサーバ１１０は、以上のようにしてソケット・バッファに送られたデータを、 HTTP レスポンスとしてクライアント２００へ送信する。
【００５７】
以上の動作を FastCGI パケット の具体例で説明する。文字列ファイル名「/tmp/str_0001.html」またはリンク名「/tmp/str_0001.html-link」に基づいて、ファイルがソケット・バッファに送られる（図７のステップ７０５参照）。この後、まだボディ部の最後に達していない場合には、ステップ７０３以降の処理を繰り返し、次のオフセットの文字がソケット・バッファに送られる（Ｓ７０４）。
【００５８】
以上、本実施形態について説明したが、本発明の技術的範囲は上記実施形態に記載の範囲には限定されない。例えば、上記実施形態では、アプリケーション実行部１２０を PHP 言語処理系として説明したが、HTMLファイルにスクリプトを記述できる他の処理系であっても良い。また、HTTPサーバ１１０とアプリケーション実行部１２０との間の通信チャネル（ＳＡＰＩ）を FastCGI としたが、 mod_php 等の他のＳＡＰＩであっても良い。その他、上記実施形態に、種々の変更または改良を加えたものも、本発明の技術的範囲に含まれることは、特許請求の範囲の記載から明らかである。
【図面の簡単な説明】
【００５９】
【図１】本実施形態のウェブ・アプリケーション・サーバの機能構成を示す図である。
【図２】本実施形態が適用されるコンピュータのハードウェア構成例を示す図である。
【図３】本実施形態で用いられる PHP スクリプトの例を示す図である。
【図４】本実施形態の拡張ライブラリによるアプリケーション実行部の動作を示すフローチャートである。
【図５】本実施形態のプロファリング処理のフローチャートである。
【図６】本実施形態に実行時処理のフローチャートである。
【図７】本実施形態によるHTMLファイルの送信時のHTTPサーバによるデータ処理の動作を示すフローチャートである。
【図８】本実施形態によるランタイムの動作を示す図である。
【図９】本実施形態の変数の置換の例を示す図である。
【図１０】本実施形態の文字列出現テーブルを説明する図である。
【符号の説明】
【００６０】
１００…ウェブ・アプリケーション・サーバ、１１０…HTTPサーバ、１２０…アプリケーション実行部、１２１…ランタイム、１２２…拡張ライブラリ、１３０…OS実行部、１４０…記憶装置、２００…クライアント
【図１】
2010250653.tif 000003
【図２】
2010250653.tif 000004
【図３】
2010250653.tif 000005
【図４】
2010250653.tif 000006
【図５】
2010250653.tif 000007
【図６】
2010250653.tif 000008
【図７】
2010250653.tif 000009
【図８】
2010250653.tif 000010
【図９】
2010250653.tif 000011
【図１０】
2010250653.tif 000012