- PR -

printlnについて

投稿者投稿内容
koseki
ベテラン
会議室デビュー日: 2002/08/01
投稿数: 93
投稿日時: 2002-09-04 20:18
Javaは初心者なので、質問がうまくできないかもしれませんが、
よろしくお願い致します。

Servletの中で作成したResponseデータを
一回のout.printlnで出力した時、
すごく時間がかかっています。

35445バイトを出力するだけで4秒かかり、CPU使用率
まで50%に上がってしまいます。
(最近買ったサーバーで、2CPUです。遅いはずはありません。)

この時間はout.printlnの前後の時間を計りました。
何が原因なのか見当が付きません。

out.printlnを50バイトずつにしても変わりませんでした。

out.printlnは何をしているのでしょうか?
ファイルを作成している?回線に流している?

何か対策方法がありましたら、ご教授願います。

t-wata
大ベテラン
会議室デビュー日: 2002/07/12
投稿数: 209
お住まい・勤務地: 東京
投稿日時: 2002-09-05 00:47
> Servletの中で作成したResponseデータを
> 一回のout.printlnで出力した時、
> すごく時間がかかっています。

何かオブジェクトに文字列を生成するための情報とか入れて
そこから文字列を取り出しながら出力してるんですよね?
printlnに時間がかかっているのではなく、printlnに渡している
引数の生成に時間がかかっているのでは?

> out.printlnは何をしているのでしょうか?

引数に与えられた文字列(またはObjectや、プリミティブ型、char[]型)を
ブラウザ側に送信する処理をします。
実際には送信するのではなく、バッファリングしているので、このメソッド
が遅いと言うことは考えにくいのですが。
koseki
ベテラン
会議室デビュー日: 2002/08/01
投稿数: 93
投稿日時: 2002-09-05 10:49
ご回答ありがとうございます。

XMLの文字列を一つのStringに入れて
out.println(strXML)とやっています。

out.printlnの前後で時間を計ってみました。
そうしたら時間がかかり、CPU使用率も一気に上がります。

koseki
ベテラン
会議室デビュー日: 2002/08/01
投稿数: 93
投稿日時: 2002-09-05 11:01
ごめんなさい。
原因は違う所にありました。
生成したXMLの余計な改行やスペースを取るクラスが
重かったようです。
文字列バイト分回している為、長くなればなるほど時間が掛かって
いるようです。
軽いReplace関数ってどの様に作ったらいいでしょうか?

ご迷惑をお掛けしました。
H2
ぬし
会議室デビュー日: 2001/09/06
投稿数: 586
お住まい・勤務地: 港
投稿日時: 2002-09-05 11:26
ちょっと実験。

50KB分の文字列をoutに出力したところ、

日本語だと 平均2.5ミリ秒
英語だと 平均0.8ミリ秒

という結果がでました。APIにも書かれているように、おそらくエンコーディングの処理をするために、多少の時間がかかってしまうのではないでしょうか。SJISしか試していないので、EUCなどのほかのエンコーディングだとまた違うかもしれません。

ただ、私のマシンはそこまで高性能ではないので、4秒というのはかかりすぎなのかもしれません。CPU時間がはねあがるのは普通です。OSがCPUを効率よく使おうとするためです。

ところで使っている環境はなんでしょうか?

#あぁ、ほかのレポートがあるのにこんなことやってていいのだろうか・・・

テスト環境
Intel PentiumIII 500MHz × 1 : RAM 384MB
WinXP Professional (英語)
Tomcat 4.0.4 (スタンドアローン)
Java SDK + JRE 1.4.0_01
ローカルホスト上でのテスト

テストコード
コード:

//日本語SJISで出力
    public void doGet(
        HttpServletRequest request,
        HttpServletResponse response
    ) throws ServletException, IOException {
        response.setContentType("text/html;charset=SJIS"); //日本語SJIS
        PrintWriter out = response.getWriter();

        //テスト文字列の生成・25600×2Bytes = 50KBytes
        StringBuffer sb = new StringBuffer();
        for(int i=0; i<25600; ++i) {
            sb.append("は");
        }

        //テスト文字列をStringに変換
        String s = sb.toString();
        out.println("<HTML>"+"<BODY>");

        //テスト文字列の出力+前後の時間を計る
        System.out.println(System.currentTimeMillis());
        out.println(s);
        System.out.println(System.currentTimeMillis());

        out.println("</body>"+"</html>");
   }

//英語で出力
    public void doGet(
        HttpServletRequest request,
        HttpServletResponse response
    ) throws ServletException, IOException {

        response.setContentType("text/html"); //英語
        PrintWriter out = response.getWriter();

        //テスト文字列の生成・25600×2Bytes = 50KBytes
        StringBuffer sb = new StringBuffer();
        for(int i=0; i<25600; ++i) {
            sb.append("aa");
        }

        //Stringに変換
        String s = sb.toString();
        out.println("<HTML>"+"<BODY>");

        //テスト文字列の出力+前後の時間を計る
        System.out.println(System.currentTimeMillis());
        out.println(s);
        System.out.println(System.currentTimeMillis());

        out.println("</body>"+"</html>");
   }


H2
ぬし
会議室デビュー日: 2001/09/06
投稿数: 586
お住まい・勤務地: 港
投稿日時: 2002-09-05 11:28
が〜ん。解決してたんですね・・・
koseki
ベテラン
会議室デビュー日: 2002/08/01
投稿数: 93
投稿日時: 2002-09-05 13:27
H2さん、ありがとうございます。
解決してしまいました。

しかし、XMLの余計な改行コード、スペースを取るのに
処理効率が良い方法があればいいのですが、
何かありませんか?
ad hoc
会議室デビュー日: 2002/08/03
投稿数: 5
投稿日時: 2002-09-05 16:20
引用:

しかし、XMLの余計な改行コード、スペースを取るのに
処理効率が良い方法があればいいのですが、
何かありませんか?


通常、XMLでは余計な改行コードやスペースは存在しないはずです。
もし"余計"だと感じる値があるのならそれはXMLの書き方が悪いのでしょう。

<tag>

</tag>
のような書き方をしていませんか?

<tag>値</tag>
のようにしないと改行コードも値として扱われますよ。

スキルアップ/キャリアアップ(JOB@IT)