Mercurial > hg > Papers > 2019 > koo-prosym
changeset 3:3926216e699f
modify
author | e165727 <e165727@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 08 Nov 2019 21:08:33 +0900 |
parents | fdb00b58c78c |
children | d33d89b2dce4 |
files | Paper/images/abyss.pdf Paper/koo.aux Paper/koo.log Paper/koo.pdf Paper/koo.synctex.gz Paper/koo.tex |
diffstat | 6 files changed, 98 insertions(+), 98 deletions(-) [+] |
line wrap: on
line diff
--- a/Paper/koo.aux Fri Nov 08 13:51:06 2019 +0900 +++ b/Paper/koo.aux Fri Nov 08 21:08:33 2019 +0900 @@ -2,32 +2,29 @@ \newlabel{ipsj@firstpage}{{}{1}} \@writefile{toc}{\contentsline {section}{\numberline {1}\hskip 1zw{Perl6 の起動時間の改善}}{1}} \@writefile{toc}{\contentsline {section}{\numberline {2}\hskip 1zw{Perl6}}{1}} -\@writefile{toc}{\contentsline {subsection}{\numberline {2.1}{Perl6 の構想}}{1}} \providecommand*\caption@xref[2]{\@setref\relax\@undefined{#1}} \newlabel{fig:perl6cbcinter}{{1}{2}} -\@writefile{toc}{\contentsline {subsection}{\numberline {2.2}{MoarVM}}{2}} -\@writefile{toc}{\contentsline {subsection}{\numberline {2.3}{NQP}}{2}} -\@writefile{toc}{\contentsline {subsection}{\numberline {2.4}{EVALFILEとMONKEY-SEE-NO-EVAL}}{3}} -\newlabel{codeseg}{{1}{3}} -\@writefile{lol}{\contentsline {lstlisting}{\numberline {1}evalのサンプルコード}{3}} -\@writefile{toc}{\contentsline {subsection}{\numberline {2.5}{なぜ Perl6 は遅いのか}}{3}} -\@writefile{toc}{\contentsline {section}{\numberline {3}\hskip 1zw{Microsoft CLR}}{3}} -\@writefile{toc}{\contentsline {section}{\numberline {4}\hskip 1zw{Perl6によるAbyssの実装}}{3}} -\@writefile{toc}{\contentsline {subsection}{\numberline {4.1}{Abyssサーバーの構成}}{3}} -\newlabel{fig:nqpbuild}{{2}{4}} -\newlabel{fig:perl6cbcinter}{{3}{4}} +\@writefile{toc}{\contentsline {subsection}{\numberline {2.1}{MoarVM}}{2}} +\@writefile{toc}{\contentsline {section}{\numberline {3}\hskip 1zw{NQP}}{2}} +\newlabel{fig:nqpbuild}{{2}{3}} +\@writefile{toc}{\contentsline {section}{\numberline {4}\hskip 1zw{なぜ Perl6 は遅いのか}}{3}} +\@writefile{toc}{\contentsline {section}{\numberline {5}\hskip 1zw{Perl6によるAbyssの実装}}{3}} +\newlabel{fig:perl6cbcinter}{{3}{3}} +\newlabel{codeseg}{{1}{4}} +\@writefile{lol}{\contentsline {lstlisting}{\numberline {1}Abyssサーバーの実装のsource code}{4}} \newlabel{codeseg}{{2}{4}} -\@writefile{lol}{\contentsline {lstlisting}{\numberline {2}Abyssサーバーのsource code}{4}} +\@writefile{lol}{\contentsline {lstlisting}{\numberline {2}クライアント側のsource code}{4}} \newlabel{codeseg}{{3}{4}} -\@writefile{lol}{\contentsline {lstlisting}{\numberline {3}クライアント側のsource code}{4}} -\@writefile{toc}{\contentsline {subsection}{\numberline {4.2}{実行時間の比較}}{4}} -\@writefile{toc}{\contentsline {section}{\numberline {5}\hskip 1zw{今後の課題}}{4}} +\@writefile{lol}{\contentsline {lstlisting}{\numberline {3}evalのサンプルコード}{4}} +\@writefile{toc}{\contentsline {section}{\numberline {6}\hskip 1zw{比較}}{4}} +\@writefile{toc}{\contentsline {section}{\numberline {7}\hskip 1zw{まとめ}}{4}} \bibcite{キー1}{1} \bibcite{キー2}{2} \bibcite{キー3}{3} \bibcite{latex}{4} \bibcite{roast}{5} \bibcite{nqp}{6} +\bibcite{designdoc}{7} \citation{*} \bibstyle{ipsjsort} \bibdata{reference}
--- a/Paper/koo.log Fri Nov 08 13:51:06 2019 +0900 +++ b/Paper/koo.log Fri Nov 08 21:08:33 2019 +0900 @@ -1,4 +1,4 @@ -This is e-pTeX, Version 3.14159265-p3.6-141210-2.6 (utf8.euc) (TeX Live 2015) (preloaded format=platex 2016.4.14) 8 NOV 2019 13:36 +This is e-pTeX, Version 3.14159265-p3.6-141210-2.6 (utf8.euc) (TeX Live 2015) (preloaded format=platex 2016.4.14) 8 NOV 2019 21:07 entering extended mode restricted \write18 enabled. file:line:error style messages enabled. @@ -270,38 +270,38 @@ (Font) Font shape `JT1/gt/m/n' tried instead on input line 64. LaTeX Font Info: Font shape `JY1/mc/bx/n' in size <11.82813> not available (Font) Font shape `JY1/gt/m/n' tried instead on input line 64. -LaTeX Font Info: Font shape `JT1/mc/bx/n' in size <9.61035> not available -(Font) Font shape `JT1/gt/m/n' tried instead on input line 84. -LaTeX Font Info: Font shape `JY1/mc/bx/n' in size <9.61035> not available -(Font) Font shape `JY1/gt/m/n' tried instead on input line 84. [1 ] File: images/Rakudo.pdf Graphic file (type pdf) - <images/Rakudo.pdf> Excluding 'comment' comment. [2] + <images/Rakudo.pdf> +LaTeX Font Info: Font shape `JT1/mc/bx/n' in size <9.61035> not available +(Font) Font shape `JT1/gt/m/n' tried instead on input line 104. +LaTeX Font Info: Font shape `JY1/mc/bx/n' in size <9.61035> not available +(Font) Font shape `JY1/gt/m/n' tried instead on input line 104. + Excluding 'comment' comment. File: fig/tgraph.pdf Graphic file (type pdf) - <fig/tgraph.pdf> -Underfull \hbox (badness 10000) in paragraph at lines 162--162 -[]\OT1/cmr/bx/n/9.61035 EVALFILE \JY1/gt/m/n/9.61035 と \OT1/cmr/bx/n/9.61035 M -ONKEY-SEE-NO- - [] + <fig/tgraph.pdf> [2] +File: images/abyss.pdf Graphic file (type pdf) -(./code/eval.p6) [3] -File: images/abyss.pdf Graphic file (type pdf) - <images/abyss.pdf> -Overfull \hbox (21.64644pt too wide) in paragraph at lines 193--194 +<images/abyss.pdf> +Overfull \hbox (21.64644pt too wide) in paragraph at lines 178--179 [] [] -(./code/abyss.p6 +[3] (./code/abyss.p6 Overfull \hbox (4.58815pt too wide) in paragraph at lines 6--7 [][] [] -) (./code/client.p6) [4] -LaTeX Font Info: Calculating math sizes for size <8.8711> on input line 227. +) (./code/client.p6) (./code/eval.p6) [4] +LaTeX Font Info: Calculating math sizes for size <8.8711> on input line 229. + +Underfull \hbox (badness 5260) in paragraph at lines 236--237 +[]\OT1/cmr/m/n/8.8711 ThePerlFoundation: Perl 6 De-sign Docu- + [] No file koo.bbl. [5 @@ -313,11 +313,11 @@ ) Here is how much of TeX's memory you used: 4110 strings out of 493777 - 61881 string characters out of 6151334 - 181664 words of memory out of 5000000 + 61875 string characters out of 6151334 + 250664 words of memory out of 5000000 7566 multiletter control sequences out of 15000+600000 28364 words of font info for 125 fonts, out of 8000000 for 9000 929 hyphenation exceptions out of 8191 - 36i,7n,49p,639b,1446s stack positions out of 5000i,500n,10000p,200000b,80000s + 36i,7n,49p,639b,1118s stack positions out of 5000i,500n,10000p,200000b,80000s -Output written on koo.dvi (5 pages, 26752 bytes). +Output written on koo.dvi (5 pages, 27372 bytes).
--- a/Paper/koo.tex Fri Nov 08 13:51:06 2019 +0900 +++ b/Paper/koo.tex Fri Nov 08 21:08:33 2019 +0900 @@ -49,7 +49,7 @@ Perl6 の実装の一つであるRakudoは, Byte code である MoarVM と, その上で動作する Perl6 のsubsetである nqp (Not Quite Perl) 上に構成されている, 現状の Perl6 の実行は Perl6 で記述されたコンパイラを load して JIT しながら実行すること自体に時間がかかっている. -そこで, Perl6 をサーバーとして動作させ, 実行するファイルをサーバーに投げて実行する方法を実装してみた. これにより高速化を実現できた. +そこで, Perl6 をサーバーとして動作させ, 実行するファイルをサーバーに投げて実行する方法を実装してみた. 本論文では, サーバーで script 言語を実行する場合の利点と欠点について考察する. \end{abstract} @@ -65,23 +65,21 @@ 現在開発の進んでいる言語に Perl6 がある. スクリプト言語 Perl6 は任意の VM が選択できるようになっており, 主に利用されている VM に C で書かれた MoarVM が存在する. MoarVM は JIT コンパイルなどをサポートしているが, 全体的な起動時間及び処理速度が Perl5 や Python , Ruby などの他のスクリプト言語と比較し非常に低速である. -その為, 現在日本国内では Perl6 は実務としてあまりない. +その為, 現在日本国内では Perl6 は実務としてあまり使われていない. Perl6 の持つ言語機能や型システムは非常に柔軟かつ強力であるため, 実用的な処理速度に達すれば, 言語の利用件数が向上することが期待される. -Perl6 は MoarVM に基づくJIT コンパイラを持っており,コンパイルされた結果はプロセッサが実行可能な機械語に相当する +Perl6 は MoarVM に基づくJIT コンパイラを持っており,コンパイルされた結果はプロセッサが実行可能な機械語に相当する. しかし現状の Perl6 は起動時間が非常に遅いことが問題である. この問題を解決するために, 実行するファイル名をサーバーに転送し,サーバー上であらかじめ立ち上げておいたコンパイラでコンパイルを行う手法を提案する. -またサーバーでは,サーバーに投げられた Raku をコンパイラで実行する際に,そのスクリプトが次に実行するスクリプトに影響を与えないことを保証する必要がある. +またサーバーでは,サーバーに投げられた Perl6 をコンパイラで実行する際に, そのスクリプトが次に実行するスクリプトに影響を与えないことを保証する必要がある. この問題を解決するために,本研究ではサーバーのコンテナ化を行う. + 研究をするにあたり得られた, サーバー上でscript言語を実行する場合の利点と欠点について述べ, 今後の展望について記載する. \section{Perl6} -この章では現在までの Perl6 の遍歴及び Perl6 の言語的な特徴について記載する. - -\subsection{Perl6 の構想} Perl6 は 2002 年に LarryWall が Perl を置き換える言語として設計を開始した. Perl5 の言語的な問題点であるオブジェクト指向機能の強力なサポートなどを取り入れた言語として設計された. Perl5 は設計と実装が同一であり, Larry らによって書かれた C 実装のみだった. Perl6 は設計と実装が分離している. 言語的な特徴としては, 独自に Perl6 の文法を拡張可能な Grammar, Perl5 と比較した場合のオブジェクト指向言語としての進化も見られる. また Perl6 は漸進的型付け言語である. 従来の Perl の様に変数に代入する対象の型や, 文脈に応じて型を変更する動的型言語としての側面を持ちつつ, 独自に定義した型を始めとする様々な型に, 静的に変数の型を設定する事が可能である. Perl6 は言語仕様及び処理実装が Perl5 と大幅に異なっており, 言語的な互換性が存在しない. 従って現在では Perl6 と Perl5 は別言語としての開発方針になっている. Perl6 は現在有力な処理系である Rakudo から名前を取り Raku という別名がつけられている. @@ -107,15 +105,15 @@ MoarVM は Raku に特化した VM である. C 言語で実装されている. JIT コンパイルなどが現在導入されているが, 起動時間などが低速である問題がある. MoarVM 独自の ByteCode があり, NQP からこれを出力する機能などが存在している. -\subsection{NQP} +\section{NQP} \begin{comment} -NQP とは Raku のサブセットである. -その為基本的な文法などは Raku に準拠しているが,変数を束縛で宣言するなどの違いが見られる. +%NQP とは Raku のサブセットである. +%その為基本的な文法などは Raku に準拠しているが,変数を束縛で宣言するなどの違いが見られる. -NQP は最終的には NQP 自身でブートストラップする言語であるが,ビルドの最初にはすでに書かれた MoarvM ByteCode を必要とする. -この MoarVMByteCode の状態を Stage0 と言う. -Raku の一部は NQP を拡張したもので書かれている為, Rakudo を動作させる為には MoarVM などの VM , VM に対応させる様にビルドした NQP がそれぞれ必要となる. -NQP は与えられた Stage0 を使い Stage1 をビルドし, そのStage1 を利用し Stage2 をビルドする事で生成できる. +%NQP は最終的には NQP 自身でブートストラップする言語であるが,ビルドの最初にはすでに書かれた MoarvM ByteCode を必要とする. +%この MoarVMByteCode の状態を Stage0 と言う. +%Raku の一部は NQP を拡張したもので書かれている為, Rakudo を動作させる為には MoarVM などの VM , VM に対応させる様にビルドした NQP がそれぞれ必要となる. +%NQP は与えられた Stage0 を使い Stage1 をビルドし, そのStage1 を利用し Stage2 をビルドする事で生成できる. \end{comment} RakudoにおけるNQPは現在MoarVM, JVM上で動作する. @@ -159,33 +157,20 @@ %従ってyaccやlexと言ったPerl5の文字解析, 構文解析に利用していたプログラムは利用せず, NQP側で構文定義などを行っている. %NQPはNQP自身でBootstrappingされている為, Rakudo Perl6のbuild時にはNQPの実行環境として要したVM, それに基づいてbuildしたNQPがそれぞれ必要となる. -\subsection{EVALFILEとMONKEY-SEE-NO-EVAL} -Perl6にはEVALというものがある. -通常, 変数や埋め込みコードを含む文字列などの入力は, デフォルトでは無効ですが, EVALは文字列リテラルとして受け取ったものをプログラムとしてそのまま解釈し, オーバーライドできます. -Perl6では, EVALは非常に危険な関数であるため通常時は使用できないようになっているが, 下記のようにMONKEY-SEE-NO-EVAL というpragmaを動作させることによって使用することができるようになる. -\lstinputlisting[label=codeseg, caption=evalのサンプルコード]{code/eval.p6} - -\subsection{なぜ Perl6 は遅いのか} -通常Rubyのようなスクリプト言語ではまずrubyVMが起動し,その後スクリプトをByte code に変換して実行という手順を踏む. +\section{なぜ Perl6 は遅いのか} +通常 Ruby のようなスクリプト言語ではまず YARVなどのプロセスVM が起動し,その後スクリプトを Byte code に変換して実行という手順を踏む. Rakudo はインタプリタの起動時間及び、 全体的な処理時間が他のスクリプト言語と比較して非常に低速である. -これはRakudo自体がRakuで書かれているため, MoarVMを起動し, Rakudo と NQP をコンパイルし, その後スクリプトのByte code 変換というような手順で進むためである. +これは Rakudo 自体が Perl6 と NQP で書かれているため, MoarVMを起動し, Rakudo と NQP のByte codeを読み取り, Rakudoを起動し, その後スクリプトを読み取り, スクリプトの Byte code 変換というような手順で進むためである. また Raku は実行時の情報が必要であり, メソッドを実行する際に invoke が走ることも遅い原因である. -\section{Microsoft CLR} -.NET Framework には, 共通言語ランタイム(Common Language Runtime)と呼ばれるランタイム環境がある. -.NET対応のソフトウェアは、様々なプログラミング言語で書かれたソースコードから, いったん共通中間言語 ( Common Intermediate Language )による形式に変換されて利用者のもとに配布される. -CIL形式のプログラムを解釈し, コンピュータが直に実行可能な機械語によるプログラムに変換して実行するソフトウェアがCLRである. - +\section{Perl6によるAbyssの実装} -\section{Perl6によるAbyssの実装} -ここではAbyssサーバーについて説明する. +提案手法で実装したAbyss サーバーは Perl6 で書かれているクライアント側から投げられた Perl6 を実行するためのサーバーである. +図3は Abyss サーバーを用いたスクリプト言語実行手順である. +Abyss サーバーはユーザーがPerl6を直接立ち上げるのではなく,まず図3右側のAbyssサーバーを起動し,ユーザーはAbyssサーバーにファイルパスをソケット通信で送り,Abyssサーバーがファイルを開き実行し,その実行結果をユーザーに返す. -\subsection{Abyssサーバーの構成} -AbyssサーバーはRakuで書かれている. クライアント側から投げられたRakuを実行するためのサーバーである. -図1はAbyssサーバーを用いたスクリプト言語実行手順である. AbyssサーバーはユーザーがRakuを実行する際,クライアント側から転送されてきたファイルを事前に起動してあるサーバー側が処理し,その実行結果を返す構造となっている. - -この手法を用いることで,サーバー上で事前にRakudoを起動したRakudoを再利用し,投げられたRakuスクリプトの実行を行うためRakudoの起動時間を短縮できると推測できる. +この手法を用いることで, サーバー上で事前に起動した Rakudo を再利用し, 投げられた Raku スクリプトの実行を行うため, Rakudo の全体的な処理時間を短縮できると推測できる. \begin{figure}[H] @@ -197,44 +182,62 @@ \end{figure} Code1はAbyss サーバーのソースコードである. -Abyssサーバーは起動すると,まず自身にファイルを転送するためのソケットを生成し,その後ファイルを受け取るための待機ループに入る. +Abyssサーバーは起動すると,まず自身にファイルパスを転送するためのソケットを生成し,その後ファイルを受け取るための待機ループに入る. -ファイルパスを受け取るとファイルパスをバッファーに変換し読み込む,その後読み込んだバッファーを文字列にデコードし,ファイルパスの文字列を読み込み,ファイルの中身を式として評価するEVALFILEを用いて,プログラムを実行する. -Code1の2行目にあるMONKEY−SEE−NO−EVALはRaku上でEVALFILEを使用可能にするpragmaである. -現状のRakuのEVALFILEでは,出力がサーバー側に返っているので,クライアント側から出力を見るためにクライアント側に返す必要がある. +Perl6ではEVAL関数があり文字列をPerl6のソースコード自身として評価できる -\lstinputlisting[label=codeseg, caption=Abyssサーバーのsource code]{code/abyss.p6} -\lstinputlisting[label=codeseg, caption=クライアント側のsource code]{code/client.p6} -%通常、自分でプロセス立ち上げてPerl6を実行する際は, -%\section{問題点} -\subsection{実行時間の比較} +Perl6では, EVALは通常は使用できないようになっており, MONKEY-SEE-NO-EVALというpragmaを実行することで使うことができるようになる. +EVALFILEはファイルパスを受け取るとファイル開き, バイト文字列に変換し読み込む,その後読み込んだバイト文字列にデコードし,ファイルパスの文字列を読み込み,ファイルの中身をEVALと同様に解釈する. +Code1の2行目にあるMONKEY−SEE−NO−EVALはRaku上でEVALFILEを使用可能にするpragmaである. -\section{今後の課題} -中間予稿までにPerl6スクリプトを投げて実行するサーバーの実装、および「自分でプロセス立ち上げてPerl6実行する手法」と「既にあるサーバーに投げてPerl6スクリプトを実行する手法」の差を測るために時間の計測を行った。 +\lstinputlisting[label=codeseg, caption=Abyssサーバーの実装のsource code]{code/abyss.p6} +\lstinputlisting[label=codeseg, caption=クライアント側のsource code]{code/client.p6} +\lstinputlisting[label=codeseg, caption=evalのサンプルコード]{code/eval.p6} +%通常、自分でプロセス立ち上げてPerl6を実行する際は, +%\section{問題点} + +\section{比較} +\begin{itemize} +\item{Microsoft CLR} + +.NET Framework には, 共通言語ランタイム(Common Language Runtime)と呼ばれるランタイム環境がある. +.NET対応のソフトウェアは、様々なプログラミング言語で書かれたソースコードから, いったん共通中間言語 ( Common Intermediate Language )による形式に変換されて利用者のもとに配布される. +CIL形式のプログラムを解釈し, コンピュータが直に実行可能な機械語によるプログラムに変換して実行するソフトウェアがCLRである. +現状のAbyssサーバーはprocessとして立ち上げているが, CLRはOSに直接組み込む必要があるが, Abyssサーバーはプロセス上で実行しているためOSに手を加えず実装が容易である. -今回実装したサーバーでは,別のスクリプトを実行する前にサーバーのコンテナ化をできていないので次回以降の課題とする. -今回の実装ではTCPソケットを用いたがTCPソケットを用いるとサーバーを立ち上げた際に外部からファイルを転送される可能性があるので,Unix domain socketの実装を行い,それを用いたクライアント・サーバーを作成することで安全性が高まると考えた +\item{PyPy} + +PyPy は Python の 実装の一つであり, Cpython のサブセットである RPython で記述された 処理系である. + +PyPy は JIT コンパイル を採用しており, 実行時にコードを機械語にコンパイルして効率的に実行させることができる. +PyPy は Cpython より実行速度が速いが起動速度は Cpython と比較して約3倍遅い. + + +\end{itemize} + +\section{まとめ} +本稿では実行する Perl6 ファイル名をサーバーに転送し,コンパイラサーバーでコンパイルを行い実行することで全体的に処理時間が早くなることを示した. +\\ +他の Python のようなscript 言語にも応用できる見込みが立った. +コンパイラの起動だけでなく, モジュールの読み込みが遅い言語などを, あらかじめサーバーを側でモジュールを読み込んでおき, それを利用してプログラムを実行する手法で解決できる見込みが立った. +今回の実装ではTCPソケットを用いたがTCPソケットを用いるとサーバーを立ち上げた際に外部からファイルを転送される可能性があるので,Unix domain socketの実装を行い,それを用いたクライアント・サーバーを作成することで安全性が高まると考えた. Rakuには現状Unix domainソケットの実装がないので、Unix domainソケットを実装し、自分以外が実行できないようにすることが今後の課題に挙げられる. -また今回例題として用いたものはスクリプト言語Rakuであったが,その他のスクリプト言語にも応用が利くかどうか検討する必要はある - -今回用いたRakuのEVALFILE自体にクライアント側に出力を返す実装追加することも今後の課題に挙げられる. - -\begin{acknowledgment} -謝辞が必要であれば,ここに書く. -\end{acknowledgment} +現状のRakuのEVALFILEでは,出力がサーバー側に返っているので,クライアント側から出力を見るためにクライアント側に返す必要がある. +今回用いた Perl6 の EVALFILE 自体にクライアント側に出力を返す実装追加することも今後の課題に挙げられる. \begin{thebibliography}{9} \bibitem{キー1} Andrew Shitov. Perl6 Deep Dive - \bibitem{キー2} 清水隆博, 河野真治. CbC を用いた Perl6 処理系. 琉球大学工学部情報工学科平成 30 年度学位論文 (学士), 2018. - \bibitem{キー3} Perl6 Documentation\\{https://docs.perl6.org} (2019/10/22 アクセス) + \bibitem{キー2} 清水隆博, 河野真治. CbC を用いた Perl6 処理系. プログラミングシンポジウム論文, 2019. + \bibitem{キー3} Perl6 Documentation\\({https://docs.perl6.org}) (2019/10/22 アクセス) \bibitem{latex} 奥村晴彦, 黒木裕介: \textbf{LaTeX2e美文書作成入門}. 技術評論社, 2013. - \bibitem{roast}The Official Raku Test Suite \\{https://github.com/perl6/roast/} - \bibitem{nqp}NQP - Not Quite Perl \\{https://github.com/perl6/nqp} + \bibitem{roast}The Official Raku Test Suite \\({https://github.com/perl6/roast/}) + \bibitem{nqp}NQP - Not Quite Perl \\({https://github.com/perl6/nqp}) + \bibitem{designdoc}ThePerlFoundation: Perl 6 Design Docu- ments, ThePerlFoundation (online), available from ({https://design.raku.org}) \end{thebibliography} \nocite{*} \bibliographystyle{ipsjsort} \bibliography{reference} -\end{document} +\end{document} \ No newline at end of file