2010年10月9日土曜日

バッファ最大アロケーションサイズに依存したパフォーマンス問題(mbedのHTTPClientとHTTPText)

mbedはネットワークライブラリも充実していますので、HTTPサーバに接続してデータを取ってくる事も簡単にできてしまいます。先日、あるアプリケーションを設計実装した後で気付いたパフォーマンス問題についてここで述べたいと思います。

きっかけはこうでした。
  • 「HTTPサーバから数百バイトのデータを読んでいるだけなのになんで30秒もかかるんだ?」
  • 「おかしいなぁ。数十バイトなら1秒もかからないで読めるぞ。」
  • 「なんで読み出しバイトサイズにリニアに比例してないんだ?」
  • 「そういえばローカルバッファはどうなってるんだっけ?」
  • 「HTTPTextにデフォルトバッファサイズがあるなぁ。」
幾つかの断片的な情報をつなぎ合わせてくると疑問が湧いてきます。
  1. 「数十バイトのテキストをリクエストする分には1秒ほどで済む。」
  2. 「テキストをどんどん大きくしていったらどういう風になるだろう?」
  3. 「パフォーマンスとHTTPTextのバッファサイズとどういう関係があるのだろう?」
そこで実験してみることにしました。

サイズの異なる複数のテキストファイルを準備しました。
例えば32バイトであればhttp://mbed.org/media/uploads/shintamainjp/textfile_32bytes.txtのような感じです。

次にテストプログラムを実装しました。
テストは
  1. HTTPサーバからテキストファイルを読み込む。
  2. HTTPTextのバッファサイズは8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096を試行する。
  3. テキストのファイルサイズは8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096を試行する。
要するに10x10で合計100の条件を与え、HTTPTextのバッファサイズとHTTPサーバ上にあるファイルサイズとの相関関係を見る形を取りました。
http://mbed.org/users/shintamainjp/programs/PerformanceProblemsWithHTTPText/latest

出力結果は以下の通り

(Buffer size of a HTTPText : 8)
+---------+--------+----+
|File size|Time[ms]|Code|
+---------+--------+----+
|        8|   31525| 200|
|       16|   30976| 200|
|       32|   30974| 200|
|       64|   30976| 200|
|      128|   30978| 200|
|      256|   30974| 200|
|      512|   30971| 200|
|     1024|   30974| 200|
|     2048|   30975| 200|
|     4096|   30976| 200|
+---------+--------+----+

(Buffer size of a HTTPText : 16)
+---------+--------+----+
|File size|Time[ms]|Code|
+---------+--------+----+
|        8|     831| 200|
|       16|   30977| 200|
|       32|   30970| 200|
|       64|   30977| 200|
|      128|   30975| 200|
|      256|   30978| 200|
|      512|   30972| 200|
|     1024|   30976| 200|
|     2048|   30976| 200|
|     4096|   30976| 200|
+---------+--------+----+

(Buffer size of a HTTPText : 32)
+---------+--------+----+
|File size|Time[ms]|Code|
+---------+--------+----+
|        8|     831| 200|
|       16|     971| 200|
|       32|   30975| 200|
|       64|   30976| 200|
|      128|   30980| 200|
|      256|   30972| 200|
|      512|   30976| 200|
|     1024|   30985| 200|
|     2048|   30966| 200|
|     4096|   30974| 200|
+---------+--------+----+

(Buffer size of a HTTPText : 64)
+---------+--------+----+
|File size|Time[ms]|Code|
+---------+--------+----+
|        8|     830| 200|
|       16|     975| 200|
|       32|     975| 200|
|       64|   30971| 200|
|      128|   30980| 200|
|      256|   30972| 200|
|      512|   30980| 200|
|     1024|   30970| 200|
|     2048|   30976| 200|
|     4096|   30975| 200|
+---------+--------+----+

(Buffer size of a HTTPText : 128)
+---------+--------+----+
|File size|Time[ms]|Code|
+---------+--------+----+
|        8|     828| 200|
|       16|     975| 200|
|       32|     974| 200|
|       64|     976| 200|
|      128|   30974| 200|
|      256|   30976| 200|
|      512|   30976| 200|
|     1024|   30975| 200|
|     2048|   30976| 200|
|     4096|   30974| 200|
+---------+--------+----+

(Buffer size of a HTTPText : 256)
+---------+--------+----+
|File size|Time[ms]|Code|
+---------+--------+----+
|        8|     829| 200|
|       16|     974| 200|
|       32|     973| 200|
|       64|     974| 200|
|      128|     974| 200|
|      256|   30975| 200|
|      512|   30977| 200|
|     1024|   30975| 200|
|     2048|   30977| 200|
|     4096|   30977| 200|
+---------+--------+----+

(Buffer size of a HTTPText : 512)
+---------+--------+----+
|File size|Time[ms]|Code|
+---------+--------+----+
|        8|     827| 200|
|       16|     975| 200|
|       32|     973| 200|
|       64|     973| 200|
|      128|     978| 200|
|      256|     969| 200|
|      512|   30975| 200|
|     1024|   30977| 200|
|     2048|   30975| 200|
|     4096|   30975| 200|
+---------+--------+----+

(Buffer size of a HTTPText : 1024)
+---------+--------+----+
|File size|Time[ms]|Code|
+---------+--------+----+
|        8|     829| 200|
|       16|     973| 200|
|       32|     973| 200|
|       64|     975| 200|
|      128|     974| 200|
|      256|     974| 200|
|      512|     975| 200|
|     1024|   30974| 200|
|     2048|   30976| 200|
|     4096|   30976| 200|
+---------+--------+----+

(Buffer size of a HTTPText : 2048)
+---------+--------+----+
|File size|Time[ms]|Code|
+---------+--------+----+
|        8|     830| 200|
|       16|     974| 200|
|       32|     977| 200|
|       64|     976| 200|
|      128|     971| 200|
|      256|     976| 200|
|      512|    1106| 200|
|     1024|     848| 200|
|     2048|   31364| 200|
|     4096|   30851| 200|
+---------+--------+----+

(Buffer size of a HTTPText : 4096)
+---------+--------+----+
|File size|Time[ms]|Code|
+---------+--------+----+
|        8|     564| 200|
|       16|     968| 200|
|       32|     973| 200|
|       64|     974| 200|
|      128|     975| 200|
|      256|     975| 200|
|      512|     971| 200|
|     1024|     976| 200|
|     2048|    1244| 200|
|     4096|   31251| 200|
+---------+--------+----+
結果を表にしてみました。


明らかにおかしな現象が確認できます。
  • バッファサイズとテキストファイルサイズとの関係で現象の有無が決まる。
  • バッファサイズがテキストファイルより小さいと問題が発生する。
HTTPClientかHTTPTextの実装に問題がありそうです。
ソースコードは公開されていませんので、ここから先はARM社の仕事になりそうです。

mbed.orgにトピックを上げておきました。
http://mbed.org/forum/bugs-suggestions/topic/1180/

0 件のコメント:

コメントを投稿