地図タイルのスピードテスト

地図タイルの読み込みスピードをjmeterを使って計測します。

jmeterの設定

jmeterではhtmlからajaxで呼び出される地図タイルの計測はできない(らしい)ので
タイルを直接呼び出す時間を計測する。

  • テスト計画→追加→Threds→スレッドグループ
    • スレッド数 5、ループ回数100
  • スレッドグループ→追加→サンプラー→HTTPリクエス
    • サーバ名 hoge.s3-website-ap-northeast-1.amazonaws.com
    • パス /hogehoge/tiles/${z}/${x}/${y}.png
  • スレッドグループ→追加→設定エレメント→CSV Data Set Config
    • filename data.csv
    • Variable Names z,x,y
  • スレッドグループ→追加→リスナ→結果を表で表示

設定ファイル(jmx)を適当な場所に保存する
data.csvを設定ファイル(jmx)と同じ場所に保存しておく

data.csvの作成

以下のスクリプトを実行して、読み込むタイルのリストdata.csvを作成する。
ランダムに作成される中心位置から各ズームレベルごとに5×4=20枚のタイルを作成する。この場合、ズームレベル11〜15の5段階なので5×20=100タイル

#!/usr/bin/env python
from math import pi,cos,sin,log,exp,atan
import sys
import random

DEG_TO_RAD = pi/180
RAD_TO_DEG = 180/pi


def minmax (a,b,c):
    a = max(a,b)
    a = min(a,c)
    return a

class GoogleProjection:
    def __init__(self,levels=18):
        self.Bc = []
        self.Cc = []
        self.zc = []
        self.Ac = []
        c = 256
        for d in range(0,levels):
            e = c/2;
            self.Bc.append(c/360.0)
            self.Cc.append(c/(2 * pi))
            self.zc.append((e,e))
            self.Ac.append(c)
            c *= 2
                
    def fromLLtoPixel(self,ll,zoom):
         d = self.zc[zoom]
         e = round(d[0] + ll[0] * self.Bc[zoom])
         f = minmax(sin(DEG_TO_RAD * ll[1]),-0.9999,0.9999)
         g = round(d[1] + 0.5*log((1+f)/(1-f))*-self.Cc[zoom])
         return (e,g)
     
    def fromPixelToLL(self,px,zoom):
         e = self.zc[zoom]
         f = (px[0] - e[0])/self.Bc[zoom]
         g = (px[1] - e[1])/-self.Cc[zoom]
         h = RAD_TO_DEG * ( 2 * atan(exp(g)) - 0.5 * pi)
         return (f,h)


def print_tiles(bbox, minZoom=1,maxZoom=18,tms_scheme=False):

    gprj = GoogleProjection(maxZoom+1) 

    ll0 = (bbox[0],bbox[3])
    ll1 = (bbox[2],bbox[1])
    
    for z in range(minZoom,maxZoom + 1):
        px0 = gprj.fromLLtoPixel(ll0,z)
        px1 = gprj.fromLLtoPixel(ll1,z)

        xnum=0
        for x in range(int(px0[0]/256.0),int(px1[0]/256.0)+1):
            if (x < 0) or (x >= 2**z):
                continue
	    xnum+=1
	    if(xnum > 5):
	 	break
            ynum=0
            for y in range(int(px0[1]/256.0),int(px1[1]/256.0)+1):
                if (y < 0) or (y >= 2**z):
                    continue
                if tms_scheme:
                    y = (2**z-1) - y
		
                print("%d,%d,%d" % (z,x,y))
		ynum+=1
		if(ynum > 4):
			break


if __name__ == "__main__":

    rnd=random.random()*10
    bbox = (135+rnd,35+rnd,136+rnd,36+rnd)
    print_tiles(bbox, 11, 15)

data_tiles.pyで保存して、以下コマンドで実行

python data_tiles.py

スピードテストの項目

  • S3
  • CloudFront + S3
  • EC2(micro) + tilestream
  • EC2(2xlarge) + tilestream
  • CloudFrare + S3
  • さくらVPS
  • レベル11〜15のgrids読み込み有り
  • レベル11〜15のgrids読み込み無し

結果

  • CloudFrontを利用すると、およそ2倍のはやさ

(でも、いまいち体感速度は変わらないような。。。
CloudFrion使えばS3のバケット名が任意でOKなので、使う方向で)

  • tilestream + micro は CloudFrontに比べて100倍おそい