AWS, さくらVPS, hetemlでベンチマークしてみた

hetemlはスゴく機能がいっぱいで使いやすくて大好きなのですが、どうも遅い。他にもAWSや、さくらVPSを使ってるのでベンチマークしてみた。

ベンチマーク方法

とりあえずPHP+MySQLの性能が図れれば一般的なwebアプリの性能が分かりやすいと思ったのでPHPspeedをやってみました。

計測対象は以下の5つです
・Local : MacOSX, Core2Duo 2.0GHz, メモリ4GB, HDD
・AWS small : EC2 smallインスタンス, Debian, シンガポール
・AWS medium : EC2 mediumインスタンス, Debian, シンガポール
・さくらVPS : Debian (カスタムOSインストール)
・heteml : OS不明

計測結果

すべて3回やって平均値です。

  Local AWS
small
AWS
medium
さくらVPS heteml
Synthetic PHP BenchMark 3,666 1,281 2,976 2,816 2,185
Synthetic MySQL BenchMark 1,615 5,613 10,028 9,281 175
Synthetic Read/Write BenchMark 1,886 798 1,950 1,784 2,053
Real World PHP & MySQL BenchMark 2,644 1,035 2,398 2,623 2,180
Server BenchMark 1,996 1,002 2,245 2,658 689

結論

イメージ的にはAWSのmediumが一番で速いのではないかと思っていて、だいたいあってる感じだったのですが、実はそれ以上にさくらVPSがかなり優秀だということがわかりました。
hetemlの遅さの原因がMySQLってのがわかりました。このへんちょっと改善してもらえれば快適になるような気がします。

まだまだサービス開始からあまり時間も経っていないので、さくらVPSが快適に使えているのかもしれませんが、コストパフォーマンスを考えてもダントツにおすすめな感じがしました。
サーバーの構築やら管理やらが苦にならないのであれば、heteml等のレンタルサーバーを借りるよりもさくらVPSSを借りて好き勝手やっちゃったほうがかなりお得な気がします。

サービス内容で比較するとAWSとさくらVPSは似て非なるサービスで、AWSのほうが色々そろってます。個人的に一番の差と感じるのがOSのイメージをS3に保存しておける点でしょうか。
さくらVPSのOSインストールもかなり簡単で、すぐ環境は用意できるのですが、やっぱりOSイメージそのものから復帰するのとはだいぶ違いますね。
このあたりは使い道とかで変わってくるとは思いますが、まぁコスト的にさくらVPSとAWSのsmallで6倍(円高ありがとう価格で)、mediumになると10倍以上の差があるのでコストパフォーマンスは抜群でしょうね。



Filed under: AWS,PHP — maesan 5:47 PM  Comments (3)

為替レートを取得するプログラム書いてみた

ちょっと自動で別通貨から日本円に変換する処理が必要になったのでなんとか自動で為替レートを取得できないかと試行錯誤してみた。

データソース

調べてみるとYahoo!ファイナンスやら証券会社のページをスクレイピングしてる人とか多いみたいですが、仕様が変わったりすると面倒だったり、何となく邪道な感じがしたので、為替レートをRSSで提供しているサイトを発見したのでそれをパースすることにしました。
使ったのはココ→http://xurrency.com/

方法

APIも用意されているみたいなのですが、アクセスキーを取得しないと1日10回までの制限があったり、商用利用じゃ無かったらお金はかからないっぽいのですが何となくAPIは使わずにRSSをパースすることにしました。
今回は日本円基準なのでhttp://xurrency.com/jpy/feedを使います。
最終的にはデータベースに格納することにしました。DBはこんな感じcakePHPとかで使えそうな構造にしました。

CREATE TABLE `currencies` (
`id` int(11) NOT NULL auto_increment,
`base` varchar(3) collate utf8_unicode_ci NOT NULL COMMENT '基準通貨',
`target` varchar(3) collate utf8_unicode_ci NOT NULL COMMENT '対象通貨',
`value` float NOT NULL COMMENT 'レート',
`inverse` float NOT NULL COMMENT 'レート逆数',
`created` datetime default NULL COMMENT '作成日時',
`modified` datetime default NULL COMMENT '更新日時',
PRIMARY KEY (`id`),
KEY `target` (`target`),
KEY `created` (`created`)
) ENGINE=InnoDB;

ソースコード

とりあえずサクっとPHPで作ってみた

<?php
// XML取得
$xml = file_get_contents('http://xurrency.com/jpy/feed');
// XML パーサー作ってパースする
$parser = xml_parser_create();
xml_parse_into_struct($parser, $xml, $values, $idx);
xml_parser_free($parser);

// とりあえずDB接続
$con = mysql_connect('localhost', 'root', 'root');
mysql_select_db('currency');
mysql_query('set names utf8');
// 挿入用のSQL
$sql_base = 'insert into currencies(base, target, value, inverse, created, modified)values("%s", "%s", %f, %f, "%s", now());';

$date = null;
foreach ($idx['DC:VALUE'] as $key => $val) {
if ($date == null) {
// RSSの構造によりdateが1個はじめにかぶるから1個ずらす
$date = date('Y-n-j H:i:s', strtotime($values[$idx['DC:DATE'][$key + 1]]['value']));
}
$data = array(
'value' => $values[$val]['value'],
'base' => $values[$idx['DC:BASECURRENCY'][$key]]['value'],
'target' => $values[$idx['DC:TARGETCURRENCY'][$key]]['value'],
'date' => $date,
);
$data['inverse'] = 1.0 / $data['value'];
$sql = sprintf($sql_base, $data['base'], $data['target'],
$data['value'], $data['inverse'],
$data['date']);
mysql_query($sql);
}
// おしまい
mysql_close($con);
?>

で見てもらうとわかると思うのですが、ちょっとXMLのパースの仕方が美しくない気がしません?何ていうか親子関係無視というかとりあえず上からパースしてタグ名でばらしてみましたみたいな?
なので最近お気に入りのPythonでも同じの書いてみた

#!/usr/bin/python
#coding -*- coding: utf-8 -*-

from xml.etree.ElementTree import ElementTree
from urllib import urlopen
import MySQLdb
import datetime

# ElementTreeを生成
xml = ElementTree(file=urlopen('http://xurrency.com/jpy/feed'))
# タグ名が"{ネームスペース}:タグ名"に展開されるのでネームスペースを書いとく
rss = 'http://purl.org/rss/1.0/'
dc = 'http://purl.org/dc/elements/1.1/'

# MySQL接続
con = MySQLdb.connect(db="currency", host="127.0.0.1", port=3306, user='root', passwd='root')
# 挿入用のSQL
base_sql = 'insert into currencies(base, target, value, inverse, created, modified)values("%(base)s", "%(target)s", %(value)f, %(inverse)f, "%(date)s", now());';

# itemタグ内に為替レートを持ってるので取得してループ回す
for items in xml.findall('.//{' + rss + '}item'):
currency = {}
for item in items.getiterator():
if item.tag == '{' + dc + '}value':
currency['value'] = float(item.text)
if item.tag == '{' + dc + '}baseCurrency':
currency['base'] = item.text
if item.tag == '{' + dc + '}targetCurrency':
currency['target'] = item.text
if item.tag == '{' + dc + '}date':
currency['date'] = datetime.datetime.strptime(item.text, "%a %b %d %H:%M:%S UTC %Y")
currency['inverse'] = 1.0 / currency['value']

sql = base_sql%{'base':currency['base'], 'target':currency['target'], 'value':currency['value'], 'inverse':currency['inverse'], 'date':currency['date']}
cur = con.cursor()
cur.execute(sql)

con.commit()

そこまでこだわるような物ではないのかもしれませんが、コッチの方が構造を解析している感じがして個人的には綺麗な気がします。

まとめ

頻繁にアクセスするのも申し訳ないので、1日に1回cronで取得してデータ溜めこむ予定。なんかに使えそうだしね。
何ていうか、とりあえず円高スゲー、早く外貨口座作ってそっちにお金移さないとダメだ。ま、そんなに日本円も持ってないけどなw

Filed under: cakePHP,PHP,Programming,Python — maesan 2:37 AM  Comments (1)

[Flex] 無理矢理多言語対応してみた

Flex(今はFlashって言ったほうがよい?)で多言語対応したかったのですが、王道でいくと言語毎にリソースファイルを用意してそれぞれでビルドするらしいです。
でもコレだと言語毎にswfファイルができてしまうので非常にめんどくさい!
なのでとりあえず無理矢理swfひとつでいけるように作ってみた。
バージョンはFlexの3でやってます。

作ったサンプル

If you can see this, then you might need a Flash Player upgrade or you need to install Flash Player if it's missing. Get Flash Player from Adobe.

ソースコード


// 現在の設定言語
private var current_language:String = "jpn";

// 英語 → 日本語 または 日本語 → 英語にする
private function change_language():void{
if (current_language == "jpn") {
current_language = "eng";
} else {
current_language = "jpn";
}
var strings:Object = msg_strings[current_language];
for (var key:String in strings) {
var obj:Object = this.getChildByName(key);
if (obj != null) {
if (obj is Label) {
obj.text = strings[key];
} else if (obj is RadioButton || obj is Button) {
obj.label = strings[key];
}
}
}
}
// 辞書的なモノ
private var msg_strings:Object = {
'eng':{
'label1':'Label',
'button1':'Button',
'radio1':'Radio1',
'radio2':'Radio2',
'button2':'To Japanese'
},
'jpn':{
'label1':'ラベル',
'button1':'ボタン',
'radio1':'ラジオ1',
'radio2':'ラジオ2',
'button2':'英語にする'
}
}

簡単な説明

change_language()で日本語の場合は英語に、英語の場合は日本語に切り替えます。
やり方は簡単で、msg_stringsのように言語毎、オブジェクトのid毎に表示する文字列を持たせておきます。辞書データとでも言いましょうか。コレはとりあえずコードに直で書いているけど、多分別ファイルとか動的にオブジェクト取ってくるとかでもイイんじゃないかと思います。

んで辞書データをループさせて対応するidのオブジェクトを取ってきてLabelオブジェクトだったらtextプロパティに、RadioButtonやButtonならlabelプロパティにいれてるだけです。

ちょっと複雑なアプリになると管理がめんどくさくなっちゃうと思いますが、簡単なアプリならこれで充分かなと思ったりしました。

Adobe Flash Builder Standard 4.0 日本語版 Windows/Macintosh版
アドビシステムズ (2010-04-09)
売り上げランキング: 338
Filed under: Flash,Flex,Programming — maesan 6:12 PM
 iTunes Store(Japan)
 iTunes Store(Japan)
 iTunes Store(Japan)
 iTunes Store(Japan)
 iTunes Store(Japan)