嬉野旅行 2 日目

2日目は 6 時に起きて、貸切じゃない方の露天風呂に行ってきた。 他の客だれもいなくて貸切だったから写真撮っておけばよかったな。

露天風呂の後は朝食。

f:id:griefworker:20150111070916j:plain

トロ鯵。朝から結構なボリューム。

f:id:griefworker:20150111071134j:plain

これが温泉湯豆腐。 煮込むと温泉の成分が作用して、豆腐がトロトロになる。 ごま醤油とごまダレ、どちらで食べても旨かった。

f:id:griefworker:20150111072203j:plain

デザートはヨーグルト。いかにも朝食っぽい。

f:id:griefworker:20150111074449j:plain

朝食食べた後は、もう一度部屋の風呂に入りつつ、 チェックアウト時間までまったり。

チェックアウトしてから高速バスの時間までは 40 分くらいしかなかったので、 嬉野観光はバスセンター近くの豊玉姫神社だけ行ってみた。 御神体の白なまずは写真撮るとバチがあたりそうな気がしたので、本殿の写真だけ。

f:id:griefworker:20150111110151j:plain

嬉野温泉、何度か行ったことあるけど、泊まったのは今回が初めて。 ホテルの部屋はコンパクトだったけど綺麗だったし、5 種類のお風呂に入れたし、 かなり満喫できた。

嬉野旅行 1 日目

食べ歩きだけでなく旅行も好きで、 毎年最低でも1回は旅行に行っている。 今年も早々、佐賀県嬉野温泉に行ってきた。 近場なので1泊2日の小旅行。

嬉野バスセンターで高速バスを降りてから、10分ほど歩いたら宿泊するホテル『萬象閣 敷島』入り口に到着。 全体を撮りたかったけど、いい撮影ポイントが無かった。

f:id:griefworker:20150110144722j:plain

受付しつつ、抹茶と敷島プリンをいただく。 敷島プリンは上に抹茶ソース、底に黒蜜が入っていて、 和風で旨かった。

f:id:griefworker:20150110150050j:plain

受付が終わってプリン食べ終わったら、部屋に案内された。 和モダンな部屋でオシャレ。

f:id:griefworker:20150110151009j:plain

部屋に露天風呂が付いている。蛇口ひねると温泉が出てくるので、 湯加減調整しながら自分で溜めるタイプ。

f:id:griefworker:20150110151116j:plain

フロントで貸切露天風呂の空き状況を確認し、16 時にさっそく貸切露天風呂へ。 まずは5番湯。 冬でも風情あっていい。 これが秋なら紅葉が綺麗なんだろうな。

f:id:griefworker:20150110155947j:plain

貸切露天風呂から上がったら、早めの夕食。

刺身は結構厚めに切ってあって食べ応えあった。

f:id:griefworker:20150110180010j:plain

佐賀有田が有名な呉豆腐。汲み湯葉も入っていた。

f:id:griefworker:20150110181409j:plain

八寸は右端の柿チーズが甘くて好き。

f:id:griefworker:20150110184458j:plain

そしてこれが佐賀牛

f:id:griefworker:20150110180032j:plain

ホームページで予約したので、佐賀県産和牛(佐賀牛ではない)も付いてきた。

f:id:griefworker:20150110181452j:plain

こんな風に自分で焼く。 結構しっかり焼いたつもりでもミディアムレア。 脂が甘くてジューシーだった。

f:id:griefworker:20150110182203j:plain

土瓶蒸しでほっと一息。

f:id:griefworker:20150110184512j:plain

伊勢海老吉野煮は弾力がブリブリと凄かった。

f:id:griefworker:20150110190039j:plain

フカヒレと、〆のお茶づけ。 初めてフカヒレ食べたけど、不思議な食感。

f:id:griefworker:20150110191146j:plain

デザートのパンナコッタが来たころには、もうお腹いっぱいではち切れそうだった。

f:id:griefworker:20150110193506j:plain

夕食で腹がパンパンになったから少し部屋で休憩し、 2度目の貸切露天風呂へ。 今度はかまくら湯。 秘密基地みたいで男心がくすぐられた。

f:id:griefworker:20150110200008j:plain

この後、大浴場と部屋の露天風呂にも入ったので、合計 4 回お風呂に入ったことになる。

さすがに疲れたので、夜はフロントで借りた『アナ雪』の DVD を部屋で見つつまったり。

f:id:griefworker:20150110203257j:plain

アナ雪いつか見ようと思っていたけど、まさか旅行先のホテルで見ることになるとは思わなかったな。

ASP.NET MVC でチャートを表示

ASP.NET MVC でレーダーチャートを表示する方法を調べたところ、 System.Web.Helpers にある Chart クラスを使うのが手っ取り早そうだった。

System.Web.Helpers は ASP.NET MVC 5 のプロジェクトを新規作成すると、 既にアセンブリ参照に含まれているから、 すぐに使えて嬉しい。

試しにレーダーチャートを出力してみる。

まず、コントローラーでレーダーチャートの画像ファイルを作成し、パスをビューに渡す。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.Helpers;
using System.Web.Mvc;

namespace ChartSample.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            var path = "sample.jpg";
            if (System.IO.File.Exists(Server.MapPath(path)))
            {
                System.IO.File.Delete(Server.MapPath(path));
            }

            var chart = new Chart(width: 400, height: 400, theme: ChartTheme.Blue);
            chart.AddTitle("レーダーチャート");
            chart.AddSeries(
                name: "サンプル1",
                chartType: "Radar",
                xValue: new[] { "ミート", "パワー", "走力", "肩力", "守備力" },
                yValues: new[] { "90", "80", "80", "90", "80" }
            );
            chart.AddSeries(
                name: "サンプル2",
                chartType: "Radar",
                xValue: new[] { "ミート", "パワー", "走力", "肩力", "守備力" },
                yValues: new[] { "70", "100", "60", "60", "60" }
            );
            chart.Save(path: Server.MapPath(path));

            ViewBag.ChartPath = path;

            return View();
        }
    }
}

ビューでは img タグを使って、レーダーチャートの画像ファイルを表示。

@{
    ViewBag.Title = "Home Page";
}

<div class="row">
    <div class="col-md-12">
        <img src="@ViewBag.ChartPath"/>
    </div>
</div>

こんな感じのレーダーチャートが表示される。

f:id:griefworker:20150108203032j:plain

見た目は上々。 あとはどこまでカスタマイズできるかだな。

PostgreSQL で Dapper を使う

.NET Server Framework がリリースされたら、Mac OS XLinux で動く .NET アプリケーションを作ることもありそう。そうなるとデータベースは PostgreSQL かなぁ。My SQLMariaDB も捨てがたい。

どちらにしても、ORM には Dapper か Entity Framework を使うと思うので、まずは PostgreSQL と Dapper の組み合わせを試してみる。

新規コンソールアプリケーションプロジェクトに NuGet で

  • Npgsql
  • Dapper

を追加し、Npgsql と Dapper を使ったサンプルを書いてみた。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;
using Dapper;
using Npgsql;

namespace DapperSample
{
    public class Bookmark
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public string Comment { get; set; }
        public string Url { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // 接続文字列を作成
            var builder = new NpgsqlConnectionStringBuilder()
            {
                Host = "localhost",
                Port = 5432,
                Database = "postgres",
                UserName = "postgres",
                Password = "postgres",
            };

            // TransactionScope を使って自動ロールバックする
            using (var ts = new TransactionScope())
            using (var connection = new NpgsqlConnection(builder))
            {
                connection.Open();

                // テーブル作成
                connection.Execute(
                    @"create table Bookmarks (
                          Id      serial primary key,
                          Title   varchar(100),
                          Comment text,
                          Url     varchar(250)
                      )"
                );

                // データ挿入
                connection.Execute(
                    @"insert into Bookmarks (
                          Title,
                          Comment,
                          Url
                      )
                      values (
                          'present',
                          '技術ブログ',
                          'http://tnakamura.hatenablog.com'
                      )"
                );

                // データ取得
                var bookmarks = connection.Query<Bookmark>(@"select * from Bookmarks");
                foreach (var b in bookmarks)
                {
                    Console.WriteLine(b.Id.ToString());
                    Console.WriteLine(b.Title);
                    Console.WriteLine(b.Comment);
                    Console.WriteLine(b.Url);
                    Console.WriteLine();
                }

                // テーブル削除
                connection.Execute("drop table Bookmarks");
            }

            Console.WriteLine("Enter で終了");
            Console.ReadLine();
        }
    }
}

f:id:griefworker:20150106095634p:plain

PostgreSQL でも Dapper 使えそうだ。

最小の Owin アプリケーションを Heroku にデプロイしてベンチマーク計測してみた

はじめに

heroku-buildback-mono を使えば C# で書いた WEB アプリを Heroku で動かすことができる。 ランタイムは .NET Framework じゃなくて Mono だけど。

Heroku + Mono のパフォーマンスが知りたくなったので 最小の Owin アプリケーションをデプロイして計測することにした。

コンソールアプリケーションのプロジェクトを作成

セルフホストなのでコンソールアプリケーションのプロジェクトを作成する。

NuGet パッケージを追加

NuGet パッケージマネージャーで

を追加。

Visual Studio の場合は、NuGet Package の復元を有効化しておく。 MonoDevelop(Xamarin Studio) の場合は不要だった。

最小の Owin アプリケーションを作成

using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Owin;
using Microsoft.Owin.Hosting;
using Microsoft.Owin.Host.HttpListener;

namespace OwinSample
{
  using AppFunc = Func<IDictionary<string, object>, Task>;

  public class SampleApp
  {
    public SampleApp(AppFunc next)
    {
    }

    public Task Invoke(IDictionary<string, object> environment)
    {
      var stream = (Stream)environment["owin.ResponseBody"];
      using (var writer = new StreamWriter (stream))
      {
        return writer.WriteAsync ("Hello World");
      }
    }
  }

  public class Startup
  {
    public void Configuration(IAppBuilder app)
    {
      app.Use(typeof(SampleApp));
    }
  }

  class MainClass
  {
    private static readonly ManualResetEvent _quitEvent = new ManualResetEvent(false);

    public static void Main (string[] args)
    {
      var port = 5000;
      if (0 < args.Length)
      {
        int.TryParse (args [0], out port);
      }

      Console.CancelKeyPress += (sender, e) =>
      {
        _quitEvent.Set();
        e.Cancel = true;
      };

      using (WebApp.Start<Startup>(string.Format("http://*:{0}", port)))
      {
        Console.WriteLine("Started");
        _quitEvent.WaitOne();
      }
    }
  }
}

Procfile を作成

Procfile には、コンソールアプリケーションを実行するコマンドを記述する。

web: mono OwinSample.exe $PORT

ビルドするとプロジェクトルートに exe が出力されるので、mono コマンドでそいつを起動している。

Heroku にデプロイ

Heroku のユーザー登録と SSH キー登録は済んでいる前提。

$ heroku create <your-app-name>
$ heroku config:add BUILDPACK_URL=https://github.com/friism/heroku-buildpack-mono
$ git push heroku master

を実行し、 Mono のビルドパックを使うようにしておく。

デプロイに成功したら Webブラウザでアクセスしてみる。

f:id:griefworker:20141231143512p:plain

Apatch Bench でベンチマーク計測

Ruby スタックと比較したいので、同じ合計リクエスト発行数と同時接続数で計測した。

合計リクエスト発行数&同時接続数 Requests per second[#/sec] Time per request(mean, across all concurrent requests)[ms]
-n 100 -c 100 29.40 34.015
-n 1000 -c 100 55.60 17.985
-n 1000 -c 1000 42.18 23.710
-n 3000 -c 1000 47.78 20.930
-n 2500 -c 2500 39.52 25.305
-n 3000 -c 2500 43.83 22.815

Mono スタックよりも Ruby スタックの方が性能が良かった。 今回の計測では、ともにアプリケーションサーバーを使っていないから、参考にしかならないけど。

最小のRackアプリケーションをHerokuにデプロイしてベンチマークを計測してみた

Heroku の Ruby スタックの性能が知りたかったので、 下記ような最小の Rack アプリケーションを Heroku にデプロイし、 Apatch Bentch でベンチマークを計測してみた。 Rack アプリケーションは unicorn とか使わず rackup コマンドで動かしている。

require "rack"

class SampleApp
  def call(env)
    [200, { "Content-Type" => "text/html" }, ["Hello World"]]
  end
end

run SampleApp.new

計測結果は下表の通り。すべてのリクエストが成功したものだけを載せている。

合計リクエスト発行数&同時接続数 Requests per second[#/sec] Time per request(mean, across all concurrent requests)[ms]
-n 100 -c 100 33.51 29.838
-n 1000 -c 100 57.03 17.536
-n 1000 -c 1000 36.64 27.924
-n 3000 -c 1000 45.05 22.199
-n 2500 -c 2500 41.33 24.193
-n 3000 -c 2500 45.79 21.838

同時接続数は 2500、合計リクエスト数 3000 あたりが上限だった。

2015 年の抱負

毎年恒例、最初のエントリでは今年の抱負を書くことにする。

2015 年の抱負は『最適化』。

プライベートで使える時間が減ることが確定しているので、 ダラダラとテレビやネットを見るのを止めて、 プライベートプロジェクトを進める時間を捻出したい。 情報収集は電車の中や休憩中といった隙間時間でやるようにし、 限られた時間を有効に使えるように自分を最適化していく。

あと、2014 年にリリースできなかった iOS アプリと Web サービスは必ずリリースする。 特に Web サービスは関わっているのが自分だけではないので悠長にしていられない。 iOS アプリはいい加減完成させないと、普段の情報収集が不便で仕方ない。

さらに、今年は原点回帰で.NET、特に ASP.NET に力を入れようと思っている。 ここ数年、プライベートでは Ruby(Rails) や iOS といった、WEB とモバイル寄りの技術ばかり触ってきたけど、 .NET Core のオープンソース化と .NET Server Framework の発表は、 プライベートでもコミットしたいと思い直すほどの衝撃ニュースだった。 今年のエントリは .NET ネタが増えると思う。