Category tech.

さくらのVPSはリージョンが3地点から選べるようになっている。これはDR (ディザスタリカバリ=災害復旧) 的な観点からのもので、1台だけ借りるなら、基本的にはどれでもいい。

ただし、施設のナウさでいくと

  1. 石狩
  2. 東京
  3. 大阪

となるようなので、リージョンごとに新機能の導入時期が変わったりする。ホストサーバのCPUの世代が違ったりもするみたいだけど、ガチャ要素なのでここではその話はしない。

VPSを契約しようとするとデフォルトで石狩が選択される通り、さくらインターネット的には石狩オシのように見える。

ただ、国内の通信で考えると石狩はちょっと遠いので、気になるのは遅延になる。

物理的に超えられない壁

情報伝送は光速度を超えることができない。

典型的な光ファイバーである石英ガラスの場合、屈折率は1.5程度。物質中の光速度 は、真空中の光速度 と屈折率 )から、 で求められる。

例えば、新宿・石狩間の直線距離約840kmで考えると、片道(840 km) / (c / 1.5) = 4.2029076 ミリ秒は物理的に超えられない遅延となる。RTT で考えれば 8.4ms を超えることは決してできないことになる。実際はケーブルが直線でひかれているわけではないので、これにさらに増える。

光ケーブルではなく電線の場合、導体中の速度は周囲の空間をすすむ電磁波のスピードと同じ (導体内ではなく) なので一概に言えないが真空中の光速度の6〜9割程度の速度になる。なお同軸ケーブルの場合波形短縮率という形で速度が示される。

いずれにせよ、情報伝送速度は真空中の光速度よりも「結構遅い」し、割と ms 単位はかかるという認識がいる。

実際のRTT

ちなみに、東京・石狩間のRTTはさくらインターネットの公式では平均「18msec」と書いてあるので光速度とかから計算しなくてもよろしい。

で、結局どこがいい

個人のVPSだと石狩のメリットは一切ない (個人の見解) ので、僕は新しい契約から東京リージョンにすることにしました。(今は大阪)

  1. トップ
  2. tech
  3. さくらのVPS、大阪・東京・石狩でどれを選ぶべきか

以下のような挙動をする。

var textarea = document.createElement('textarea');
textarea.value = "\r\n";
encodeURIComponent(textarea.value);
//=> "%0A"

この挙動、現在のブラウザではバグではなくて、仕様である。どういうことかというと、HTML Standard で明言されている

For historical reasons, the element's value is normalised in three different ways for three different purposes. The raw value is the value as it was originally set. It is not normalized. The API value is the value used in the value IDL attribute. It is normalised so that line breaks use U+000A LINE FEED (LF) characters. Finally, there is the value, as used in form submission and other processing models in this specification. It is normalised so that line breaks use U+000D CARRIAGE RETURN U+000A LINE FEED (CRLF) character pairs, and in addition, if necessary given the element's wrap attribute, additional line breaks are inserted to wrap the text at the given width.

https://html.spec.whatwg.org/multipage/forms.html#concept-textarea-api-value

value プロパティ代入動作 (Getter) は raw value の代入として働き、取得動作 (Setter) は API value の取得して働くという非対称的な挙動を示す。そして raw value を取得する方法はない。

  1. トップ
  2. tech
  3. textarea.value は代入すると値が変わる

SQLite で「PRIMARY KEY」を《真のプライマリキー》とするには | tech - 氾濫原 の続きです。

以下のような簡単なベンチマークスクリプトを使って差を測ってみました。

Linux の VPS と OS X とでやってみましたが、だいたいこの例では5%ぐらいの差がつくようでした。

#!/usr/bin/env perl


use v5.14;
use utf8;


use DBI;
use DBD::SQLite;
use Benchmark qw(:all) ;
use String::Random qw(random_regex random_string);


sub dbh {
	my ($db) = @_;
	my $dbh = DBI->connect('dbi:SQLite:dbname=', "", "", {
		sqlite_allow_multiple_statements => 1,
		RaiseError => 1,
		sqlite_see_if_its_a_number => 1,
		sqlite_unicode => 1,
	});
}


say "DBI::VERSION: $DBI::VERSION";
say "DBD::SQLite::VERSION: $DBD::SQLite::VERSION";
say "SQLite version: ". dbh()->{sqlite_version};


my $dbh_rowid = dbh();
$dbh_rowid->do(q{
	CREATE TABLE tfidf (
		`id` INTEGER PRIMARY KEY,
		`term` TEXT NOT NULL,
		`entry_id` INTEGER NOT NULL,
		`term_count` INTEGER NOT NULL DEFAULT 0,
		`tfidf` FLOAT NOT NULL DEFAULT 0,
		`tfidf_n` FLOAT NOT NULL DEFAULT 0
	);
	CREATE UNIQUE INDEX index_tf_term ON tfidf (`term`, `entry_id`);
	CREATE INDEX index_tf_entry_id_tfidf_n ON tfidf (`entry_id`, `tfidf_n`);
});


my $dbh_without_rowid = dbh();
$dbh_without_rowid->do(q{
	CREATE TABLE tfidf (
		`term` TEXT NOT NULL,
		`entry_id` INTEGER NOT NULL,
		`term_count` INTEGER NOT NULL DEFAULT 0,
		`tfidf` FLOAT NOT NULL DEFAULT 0,
		`tfidf_n` FLOAT NOT NULL DEFAULT 0,
		PRIMARY KEY (`term`, `entry_id`)
	) WITHOUT ROWID;
	CREATE INDEX index_tf_entry_id_tfidf_n ON tfidf (`entry_id`, `tfidf_n`);
});




say "insert";
{
	my $i = 0;
	cmpthese(-1, {
		'with rowid' => sub {
			$dbh_rowid->prepare_cached(q{
				INSERT INTO tfidf (`term`, `entry_id`, `term_count`) VALUES (?, ?, ?);
			})->execute(random_regex('[a-z]{2,10}'), $i++, 1);
		},
		'without rowid' => sub {
			$dbh_without_rowid->prepare_cached(q{
				INSERT INTO tfidf (`term`, `entry_id`, `term_count`) VALUES (?, ?, ?);
			})->execute(random_regex('[a-z]{2,10}'), $i++, 1);
		},
	});
};


say "select";
{
	my $i = 0;
	cmpthese(-1, {
		'with rowid' => sub {
			$dbh_rowid->selectall_arrayref(q{
				SELECT * FROM tfidf WHERE `term` = ? AND `entry_id` = ?
			}, { Slice => {} }, random_regex('[a-z]{2,10}'), $i++);
		},
		'without rowid' => sub {
			$dbh_without_rowid->selectall_arrayref(q{
				SELECT * FROM tfidf WHERE `term` = ? AND `entry_id` = ?
			}, { Slice => {} }, random_regex('[a-z]{2,10}'), $i++);
		},
	});
}
  1. トップ
  2. tech
  3. SQLite の WITHOUT ROWID の効果測定