Range



【説明】1ページ丸ごと呼ぶよりも、Rangeを指定した方が軽いのは明らかですが、試しに、他のケースとスピードを比べてみました。Rangeの価値は、レスポンス取得失敗時の重複のないリクエスト再開用など、スピードのみにあるわけではありませんが一応念のためということで。

【テスト内容】下記ボタンとソースの通り。
1ページ丸ごとといっても1回呼んだ程度では差がでませんから10000バイトのファイルを100回呼んで見ました(→Test1)
次に、丸ごと呼ばずに10000バイト中の100バイトだけをRangeヘッダで100回呼んで見ました(→Test2)
でも、100バイトづつに小分けしたファイルを100回呼ぶのと比べて早いんだろうか(→Test3)
とはいえ、10000バイトを一回読み込んで、100バイトづつ二小分けするのが、マシンが古くなければ、どう考えても一番はやそうだけどどれくらい違うの?(→Test4)。 全体の1部だけが1回必要なとき、Rangeで100バイト呼ぶ(→Test5)のと、全部読み込んでから100バイト表示する(→Test6)のはどれくらい違うの?


【結果】「【ベンチマーク】」欄をご覧下さい。Test1~Test4までの中では、Test2とTest3はほとんど同じ。Test4は当然1番早く、Test1は1番遅い。Test5とTest6では、RangeのTest5が早い。

【メモ】100バイトづつに小分けした手間が気にならなければ、test3はよい方法です。Operaも動きますから。しかし、Test3のような小分けに手間がかかるときにはRangeは有益でしょう。スピードではTest4です。 でも、そのTest4と同じ方法のTest6に対して、Test5(全体の1部だけが1回必要なときのRange使用)は、光で2倍、ISDNで7倍早いです。 ようは、圧倒的に有利ということではなく、目的とデータ次第ですね。<でも、この程度のファイルサイズで2~7倍のスピード差が出ているのは、もしかすると圧倒的と言っても良いかも?ISDNの1.3秒差は体感的には結構違います。<でも、Operaが使えないし。
[ave ISDN148.424sec,光sec1.141] ファイル(10000バイト)をfull Rangeでリクエストして、先頭から100バイトだけ出力を100回
[ave ISDN11.757sec,光0.594sec] ファイル(10000バイト)に対してRange 100バイト分を計100回リクエスト
[ave ISDN11.767sec,光0.904sec] あらかじめ100バイトづつに分割したファイルをfull Rangeで計100回リクエスト
[ave ISDN4.427sec,光0.254sec] ファイル(10000バイト)をfull Rangeで1回リクエストして、先頭から100バイトづつ順に出力
[ave ISDN0.210sec,光0.015sec] ファイル(10000バイト)に対してRange 100バイト分を計1回リクエスト
[ave ISDN1.542sec,光0.031sec] ファイル(10000バイト)をfull Rangeで1回リクエストして、先頭から100バイト出力

<meta http-equiv="content-script-type" content="text/javascript">
<meta http-equiv=Content-Type content="text/html; charset=utf-8">
<title>header Test</title>

<!-- Ajax簡易ライブラリ jslb_ajax.js 
     リクエストヘッダ追記テスト中v039
-->
<script languege = "JavaScript"
        src      = "../../jslb_ajax039-b2.js"
        charset  = "utf-8"></script>

<!-- ヘッダテスト用 -->
<script language = "JavaScript">
<!--

	//for bench mark test
	var startTime = 0;
	var endTime   = 0;
	var cnt = 0 ;

//シーズン1////////////////////////////////////////////////////////////


	//////////////////////////////////////////////////////////////////
	////
	// Test1:ファイル(10000バイト)をfull Rangeでリクエストして、先頭から100バイトだけ出力を100回。
	//
	function getFullRange()
	{
		cnt = 0 ;
		index=0;
		startTime = (new Date()).getTime();
		for(var i=0;i<=99;i++) getFiles('test.txt');
	}

	function getFiles(fileName)
	{
		//リクエスト
		sendRequest(on_file_loaded, '','GET','./'+fileName,true,true)
	}

	//データ受信用コールバック関数 ( 受信時に実行されます )
	function on_file_loaded(oj)
	{
	
		//ステータスコード
		status =	"【ステータスコード】<br>"+oj.status
	
		//レスポンスヘッダを取得
		headers	= "<br><br>【レスポンスヘッダ】<br>"+oj.getAllResponseHeaders().split('\n').join('<br>')
				
		//レスポンスを取得
		var res	= "【サーバーから受信したtest.txtのデータ】<br>"+oj.responseText.substr(0,100)

		endTime = (new Date()).getTime()
		saTime  = endTime - startTime
		
		//レスポンスされた文字列を表示
		document.getElementById('outputdata').innerHTML="<hr><b>【 "+cnt+" 】</b><br>"+status+headers+res
		cnt++
		
		//ベンチマーク
		endTime = (new Date()).getTime()
		saTime  = endTime - startTime
		document.getElementById('outputdata').innerHTML+="<hr><b>【ベンチマーク】"+saTime+"</b>"
	}



	//////////////////////////////////////////////////////////////////
	////
	// Test2:ファイル(10000バイト)に対してRange 100バイト分を計100回リクエスト
	//
	function getPartRange()
	{
		cnt = 0 ;
		startTime = (new Date()).getTime();

		getRange('0-99');getRange('100-199');getRange('200-299');getRange('300-399');getRange('400-499');
		getRange('500-599');getRange('600-699');getRange('700-799');getRange('800-899');getRange('900-999');

		getRange('0-99');getRange('100-199');getRange('200-299');getRange('300-399');getRange('400-499');
		getRange('500-599');getRange('600-699');getRange('700-799');getRange('800-899');getRange('900-999');

		getRange('0-99');getRange('100-199');getRange('200-299');getRange('300-399');getRange('400-499');
		getRange('500-599');getRange('600-699');getRange('700-799');getRange('800-899');getRange('900-999');

		getRange('0-99');getRange('100-199');getRange('200-299');getRange('300-399');getRange('400-499');
		getRange('500-599');getRange('600-699');getRange('700-799');getRange('800-899');getRange('900-999');

		getRange('0-99');getRange('100-199');getRange('200-299');getRange('300-399');getRange('400-499');
		getRange('500-599');getRange('600-699');getRange('700-799');getRange('800-899');getRange('900-999');

		getRange('0-99');getRange('100-199');getRange('200-299');getRange('300-399');getRange('400-499');
		getRange('500-599');getRange('600-699');getRange('700-799');getRange('800-899');getRange('900-999');

		getRange('0-99');getRange('100-199');getRange('200-299');getRange('300-399');getRange('400-499');
		getRange('500-599');getRange('600-699');getRange('700-799');getRange('800-899');getRange('900-999');

		getRange('0-99');getRange('100-199');getRange('200-299');getRange('300-399');getRange('400-499');
		getRange('500-599');getRange('600-699');getRange('700-799');getRange('800-899');getRange('900-999');

		getRange('0-99');getRange('100-199');getRange('200-299');getRange('300-399');getRange('400-499');
		getRange('500-599');getRange('600-699');getRange('700-799');getRange('800-899');getRange('900-999');

		getRange('0-99');getRange('100-199');getRange('200-299');getRange('300-399');getRange('400-499');
		getRange('500-599');getRange('600-699');getRange('700-799');getRange('800-899');getRange('900-999');
	}


	function getRange(range)
	{
		//リクエスト
		sendRequest({ 
			onload           : on_range_loaded  ,   //データ受信用コールバック
			onbeforsetheader : setHeaders     //ヘッダセット用コールバック
		}, '','GET','./test.txt',true,true)


		//リクエストヘッダセット用コールバック関数(送信直前にセットされます)
		function setHeaders(oj){
			//Rangeの値をセットしてリクエスト
			oj.setRequestHeader("Range","bytes="+range);
		}
	}

	//データ受信用コールバック関数 ( 受信時に実行されます )
	function on_range_loaded(oj)
	{
	
		//ステータスコード
		status =	"【ステータスコード】<br>"+oj.status
	
		//レスポンスヘッダを取得
		headers	= "<br><br>【レスポンスヘッダ】<br>"+oj.getAllResponseHeaders().split('\n').join('<br>')
				
		//レスポンスを取得
		var res	= "【サーバーから受信したtest.txtのデータ】<br>"+oj.responseText

		endTime = (new Date()).getTime()
		saTime  = endTime - startTime
		
		//レスポンスされた文字列を表示
		document.getElementById('outputdata').innerHTML="<hr><b>【 "+cnt+" 】</b><br>"+status+headers+res
		cnt++
		
		//ベンチマーク
		endTime = (new Date()).getTime()
		saTime  = endTime - startTime
		document.getElementById('outputdata').innerHTML+="<hr><b>【ベンチマーク】"+saTime+"</b>"
	}



	//////////////////////////////////////////////////////////////////
	////
	// Test3:あらかじめ100バイトづつに分割したファイルをfull Rangeで計100回リクエスト
	//
	function getPartFiles()
	{
		cnt = 0 ;
		startTime = (new Date()).getTime();

		getMinFiles('test0.txt');getMinFiles('test1.txt');getMinFiles('test2.txt');getMinFiles('test3.txt');getMinFiles('test4.txt');
		getMinFiles('test5.txt');getMinFiles('test6.txt');getMinFiles('test7.txt');getMinFiles('test8.txt');getMinFiles('test9.txt');

		getMinFiles('test0.txt');getMinFiles('test1.txt');getMinFiles('test2.txt');getMinFiles('test3.txt');getMinFiles('test4.txt');
		getMinFiles('test5.txt');getMinFiles('test6.txt');getMinFiles('test7.txt');getMinFiles('test8.txt');getMinFiles('test9.txt');

		getMinFiles('test0.txt');getMinFiles('test1.txt');getMinFiles('test2.txt');getMinFiles('test3.txt');getMinFiles('test4.txt');
		getMinFiles('test5.txt');getMinFiles('test6.txt');getMinFiles('test7.txt');getMinFiles('test8.txt');getMinFiles('test9.txt');

		getMinFiles('test0.txt');getMinFiles('test1.txt');getMinFiles('test2.txt');getMinFiles('test3.txt');getMinFiles('test4.txt');
		getMinFiles('test5.txt');getMinFiles('test6.txt');getMinFiles('test7.txt');getMinFiles('test8.txt');getMinFiles('test9.txt');

		getMinFiles('test0.txt');getMinFiles('test1.txt');getMinFiles('test2.txt');getMinFiles('test3.txt');getMinFiles('test4.txt');
		getMinFiles('test5.txt');getMinFiles('test6.txt');getMinFiles('test7.txt');getMinFiles('test8.txt');getMinFiles('test9.txt');

		getMinFiles('test0.txt');getMinFiles('test1.txt');getMinFiles('test2.txt');getMinFiles('test3.txt');getMinFiles('test4.txt');
		getMinFiles('test5.txt');getMinFiles('test6.txt');getMinFiles('test7.txt');getMinFiles('test8.txt');getMinFiles('test9.txt');

		getMinFiles('test0.txt');getMinFiles('test1.txt');getMinFiles('test2.txt');getMinFiles('test3.txt');getMinFiles('test4.txt');
		getMinFiles('test5.txt');getMinFiles('test6.txt');getMinFiles('test7.txt');getMinFiles('test8.txt');getMinFiles('test9.txt');

		getMinFiles('test0.txt');getMinFiles('test1.txt');getMinFiles('test2.txt');getMinFiles('test3.txt');getMinFiles('test4.txt');
		getMinFiles('test5.txt');getMinFiles('test6.txt');getMinFiles('test7.txt');getMinFiles('test8.txt');getMinFiles('test9.txt');

		getMinFiles('test0.txt');getMinFiles('test1.txt');getMinFiles('test2.txt');getMinFiles('test3.txt');getMinFiles('test4.txt');
		getMinFiles('test5.txt');getMinFiles('test6.txt');getMinFiles('test7.txt');getMinFiles('test8.txt');getMinFiles('test9.txt');

		getMinFiles('test0.txt');getMinFiles('test1.txt');getMinFiles('test2.txt');getMinFiles('test3.txt');getMinFiles('test4.txt');
		getMinFiles('test5.txt');getMinFiles('test6.txt');getMinFiles('test7.txt');getMinFiles('test8.txt');getMinFiles('test9.txt');
	}

	function getMinFiles(fileName)
	{
		//リクエスト
		sendRequest(on_minifile_loaded, '','GET','./'+fileName,true,true)
	}

	//データ受信用コールバック関数 ( 受信時に実行されます )
	function on_minifile_loaded(oj)
	{
	
		//ステータスコード
		status =	"【ステータスコード】<br>"+oj.status
	
		//レスポンスヘッダを取得
		headers	= "<br><br>【レスポンスヘッダ】<br>"+oj.getAllResponseHeaders().split('\n').join('<br>')
				
		//レスポンスを取得
		var res	= "【サーバーから受信したtest.txtのデータ】<br>"+oj.responseText

		endTime = (new Date()).getTime()
		saTime  = endTime - startTime
		
		//レスポンスされた文字列を表示
		document.getElementById('outputdata').innerHTML="<hr><b>【 "+cnt+" 】</b><br>"+status+headers+res
		cnt++
		
		//ベンチマーク
		endTime = (new Date()).getTime()
		saTime  = endTime - startTime
		document.getElementById('outputdata').innerHTML+="<hr><b>【ベンチマーク】"+saTime+"</b>"
	}



	//////////////////////////////////////////////////////////////////
	////
	// Test4:ファイル(10000バイト)をfull Rangeで1回リクエストして、先頭から100バイトづつ順に出力
	//
	
	function get_once_FullRange()
	{
		cnt = 0 ;
		index=0;
		startTime = (new Date()).getTime();
		get_once_File('test.txt');
	}

	function get_once_File(fileName)
	{
		//リクエスト
		sendRequest(on_once_file_loaded, '','GET','./'+fileName,true,true)
	}

	//データ受信用コールバック関数 ( 受信時に実行されます )
	function on_once_file_loaded(oj)
	{
	
		//ステータスコード
		status =	"【ステータスコード】<br>"+oj.status
	
		//レスポンスヘッダを取得
		headers	= "<br><br>【レスポンスヘッダ】<br>"+oj.getAllResponseHeaders().split('\n').join('<br>')
		
		for(var i=0;i<=99;i++){

			//レスポンスを取得
			var res	= "【サーバーから受信したtest.txtのデータ】<br>"+oj.responseText.substr(index,100)
			//レスポンスされた文字列を表示
			document.getElementById('outputdata').innerHTML="<hr><b>【 "+cnt+" 】</b><br>"+status+headers+res
			index+=100
			cnt++
		}
		
		//ベンチマーク
		endTime = (new Date()).getTime()
		saTime  = endTime - startTime
		document.getElementById('outputdata').innerHTML+="<hr><b>【ベンチマーク】"+saTime+"</b>"
	}


//シーズン2////////////////////////////////////////////////////////////


	//////////////////////////////////////////////////////////////////
	////
	// Test5:ファイル(10000バイト)に対してRange 100バイト分を計1回リクエスト
	//
	function test5_getPartRange()
	{
		cnt = 0 ;
		startTime = (new Date()).getTime();

		test5_getRange('0-99');
	}


	function test5_getRange(range)
	{
		//リクエスト
		sendRequest({ 
			onload           : test5_on_range_loaded  ,   //データ受信用コールバック
			onbeforsetheader : setHeaders     //ヘッダセット用コールバック
		}, '','GET','./test.txt',true,true)


		//リクエストヘッダセット用コールバック関数(送信直前にセットされます)
		function setHeaders(oj){
			//Rangeの値をセットしてリクエスト
			oj.setRequestHeader("Range","bytes="+range);
		}
	}

	//データ受信用コールバック関数 ( 受信時に実行されます )
	function test5_on_range_loaded(oj)
	{
	
		//ステータスコード
		status =	"【ステータスコード】<br>"+oj.status
	
		//レスポンスヘッダを取得
		headers	= "<br><br>【レスポンスヘッダ】<br>"+oj.getAllResponseHeaders().split('\n').join('<br>')
				
		//レスポンスを取得
		var res	= "【サーバーから受信したtest.txtのデータ】<br>"+oj.responseText

		endTime = (new Date()).getTime()
		saTime  = endTime - startTime
		
		//レスポンスされた文字列を表示
		document.getElementById('outputdata').innerHTML="<hr><b>【 "+cnt+" 】</b><br>"+status+headers+res
		cnt++
		
		//ベンチマーク
		endTime = (new Date()).getTime()
		saTime  = endTime - startTime
		document.getElementById('outputdata').innerHTML+="<hr><b>【ベンチマーク】"+saTime+"</b>"
	}




	//////////////////////////////////////////////////////////////////
	////
	// Test6:ファイル(10000バイト)をfull Rangeで1回リクエストして、先頭から100バイト筒順にだけ出力
	//
	
	function test6_get_once_FullRange()
	{
		cnt = 0 ;
		index=0;
		startTime = (new Date()).getTime();
		test6_get_once_File('test.txt');
	}

	function test6_get_once_File(fileName)
	{
		//リクエスト
		sendRequest(test6_on_once_file_loaded, '','GET','./'+fileName,true,true)
	}

	//データ受信用コールバック関数 ( 受信時に実行されます )
	function test6_on_once_file_loaded(oj)
	{
	
		//ステータスコード
		status =	"【ステータスコード】<br>"+oj.status
	
		//レスポンスヘッダを取得
		headers	= "<br><br>【レスポンスヘッダ】<br>"+oj.getAllResponseHeaders().split('\n').join('<br>')
		

		//レスポンスを取得
		var res	= "【サーバーから受信したtest.txtのデータ】<br>"+oj.responseText.substr(0,100)
		//レスポンスされた文字列を表示
		document.getElementById('outputdata').innerHTML="<hr><b>【 "+cnt+" 】</b><br>"+status+headers+res
		cnt++
		
		//ベンチマーク
		endTime = (new Date()).getTime()
		saTime  = endTime - startTime
		document.getElementById('outputdata').innerHTML+="<hr><b>【ベンチマーク】"+saTime+"</b>"
	}


//-->
</script>

<div class="input">
<input type    = "button"
       value   = "Test1:getFullRange()"
       onclick = "getFullRange()"><b> [ave ISDN148.424sec,光sec1.141]</b> ファイル(10000バイト)をfull Rangeでリクエストして、先頭から100バイトだけ出力を100回<br>
<input type    = "button"
       value   = "Test2:getPartRange()"
       onclick = "getPartRange()"><b> [ave ISDN11.757sec,光0.594sec]</b> ファイル(10000バイト)に対して<b>Range 100バイト分</b>を計100回リクエスト<br>
<input type    = "button"
       value   = "Test3:getPartFiles()"
       onclick = "getPartFiles()"><b> [ave ISDN11.767sec,光0.904sec]</b> あらかじめ100バイトづつに分割したファイルをfull Rangeで計100回リクエスト<br>
<input type    = "button"
       value   = "Test4:get_once_FullRange()"
       onclick = "get_once_FullRange()"><b> [ave ISDN4.427sec,光0.254sec]</b> ファイル(10000バイト)をfull Rangeで1回リクエストして、先頭から100バイトづつ順に出力
       
<hr>
<input type    = "button"
       value   = "Test5:test5_getPartRange()"
       onclick = "test5_getPartRange()"><b> [ave ISDN-sec,光0.015sec]</b> ファイル(10000バイト)に対して<b>Range 100バイト分を計1回</b>リクエスト<br>

<input type    = "button"
       value   = "Test6:test6_get_once_FullRange()"
       onclick = "test6_get_once_FullRange()"><b> [ave ISDN-sec,光0.031sec]</b> ファイル(10000バイト)を<b>full Rangeで1回</b>リクエストして、先頭から100バイト出力<hr>
</div>

<!-- ここへ出力 -->
<div id="outputdata"></div>
【サンプル】 【blog/Forums】
| JavaScript++かも日記 |