まだIT業界で消耗してるの? 😊ソフトウェア開発者のブログ

.NET Core Tools 1.0 が公開されて思うこと

2017年3月10日

3月7日に Visual Studio 2017 が正式リリースされましたが、それと一緒に、やっと .NET Core Tools 1.0 が正式リリースされました。.NET Core RC1 が公開されたのは、2015年11月18日でした。その当時は、ASP.NET 5 のためのフレームワークという色彩が強かったのですが、その後にいろんな経緯があって Tools の部分は1年4ヶ月もかかって正式リリースされました。いろいろあったようですが結果的には良かったよぅな気がします。

ところで、Visual Studio は今年 20 周年を迎えたそうです。自分が始めて Visual Studio を使ったのは、Visual Web Developer 2005 Express Edition でした。ASP.NET Web Form のアプリが作れるのですが、Web Form は、Web アプリを作るツールであるのもかかわらず、HTML、CSS が使いづらく、Microsoft のコンポーネントを使わないといけないという全く不便なツールでした。

それで、もう使うのを止めようと思ったのですが、Express Edition を使っていても Standard Edition のアプウグレード版を購入できるというキャンペーンがあったので、Standard Edition を購入して、ASP.NET Web Form を使わずに Web サイトを作りました。それが、徳島の交通状況 Google Maps API 版で、ソースは GitHub の TKGMapに公開しています。

Visual Studio 2015 Standard のパッケージの写真

その後も Web Form には馴染めなかったので、Python を勉強し始めました。その時に丁度 ASP.NET MVC がアナウンスされたので、それを使って見たら結構使いやすかったのでそれをメインに使うようになりました。ASP.NET Core は RC の時から使っていますが、ASP.NET MVC の時も CTP から使っていました。

.NET Core 及び ASP.NET Core については、いろいろな評価がありますが、既存のユーザーをスムーズに移行させられるかということと新しいユーザーを獲得できるかということが重要だと思います。

既存ユーザーの件については、ライブラリーの .NET Core 対応が余り進んでいないという点からみると成功していないように思います。RC から RTM になるまで 1年4ヶ月もかかってしまった原因の一つになっていると思いますが、.NET Core 2.0 に期待したいと思います。.NET Core 2.0 では、.NET Statndard 2.0 対応となり、APIが現在の2倍以上にして.NET Framework や Xamarin との互換性がよくなるということです。過去のバージョンとの互換性はやはり必要だと思います。

新規ユーザーは従来より増えているというのは確かですが、どの程度伸びるかは今後に期待したいと思います。Web Form に馴染めなかった自分に取っては、ASP.NET Core は、以前の ASP.NET MVC よりもわかりやすくなって随分よくなったと感じています。特に、Web Form の影響が大きい System.Web が無くなったのはすっきりしたと思います。

市区町村コード表(履歴付)を作成する .NET Core アプリを公開しました

2017年2月20日

国勢調査等の市区町村別の統計データを過去から集計して比較しようとすると、平成の大合併により過去のデータは合併前の市町村のデータを集計する必要があり、普通に手作業ですると非常に手間のかかる作業になります。

政府統計の総合窓口(e-stat)の統計LODで、1970年以降の標標準地域コードのデータが公開されているので、それを利用して、任意の時点での市区町村コード表の作成や対応表が作成できるデータベースを作成するコンソールアプリケーションを作成しました。

.NET Core で作成したので、Windows だけでなく、Mac や Linux でも動作するし、.NET Core はインストールも手軽で簡単に動作させられるようになったので GitHub で公開してみました。URL は、以下のとおりです。

NAreaCode

このアプリを作っていて気がついた点を2点メモしておきます。

コマンドラインの解析

コマンドラインの解析には、Microsoft.Extensions.CommandLineUtils を使いました。CommandLineUtils は、.NET Core になってやっと組み込まれた機能です。

以前の Microsoft はエンタープライズ向けのことには熱心なのですがシンプルに処理をするということにはあまり力が入っていなかったように思っていましたが、.NET Core、ASP.NET Core になって、シンプルに作りたい場合にも使いやすくなったと思います。コマンドラインの解析は、簡単そうですが実際に自分で作るとなると結構手間がかかるので、.NET Core になって改善された典型的な例だと思います。

コード表の処理速度

作成した市区町村コードのデータは、json形式にしています。例えば、期間付き市区町村コードは以下のような形式になっていて、4588件のレコードがあります。

public class StandardAreaCode
{
    [JsonProperty("id")]
    public int Id { get; set; }
    public string 名称 { get; set; }
    public string ふりがな { get; set; }
    public string 英語名 { get; set; }
    public 自治体種別 種別 { get; set;}
    //北海道、東京都島嶼部、長崎県対馬(旧)は支庁・振興局、その他の町村は郡、区は政令指定都市のコード
    public int 所属 { get; set; }
    //北海道及び旧長崎県対馬支庁の町村のみ
    public string 郡名称 { get; set; }
    public string 郡ふりがな { get; set; }
    public DateTime 施行年月日 { get; set; }
    public DateTime 廃止年月日 { get; set; }
    public List<int> 施行データ { get; set; }
    public List<int> 廃止データ { get; set; }
}

これらのデータを Web アプリケーションの中で使う時に、RDB にインポートするのは面倒なので、メモリーベースで処理をするということで、処理時間を計測してみました。都道府県毎に市区町村コードの一覧を計算する処理で、画面の例は「北海道の市区町村コード一覧」です。また、一覧を計算するコードのメインは以下のようになっていて、LINQ を使うのであれば、リストや配列の場合でも SQL Server を使うのとほぼ同じコードで書くことができます。

public IEnumerable<(int id, string 名称, string ふりがな)> GetAreaCode(int pref, DateTime date) =>
    AreaCodeList
    .Where(x => x.Id / 1000 == pref && x.施行年月日 <= date && x.廃止年月日 > date && x.所属 != 99)
    .Select(x => (id: x.Id, 名称: x.名称, ふりがな: x.ふりがな))
    .OrderBy(x => x.id);

Google Compute Engine の n1-standard-2 (AWS の m4.large とほぼ同性能)を使って処理時間を計測すると以下のようになりました。

  • ファイルサイズ 1126KB
  • データの読み込み時間 45ms
  • 計算時間 0.4~0.008ms

結果としては、SQL Server Express を使うよりも遙かに早いです。計算時間の 0.4ミリ秒は初回の計算の時で計算ルーティンやデータが CPU のキャッシュメモリーに入っていない場合の処理時間です。計算の必要なコードとデータが CPU のキャッシュメモリにキャッシュされてしまえば 0.008ms という圧倒的な速さで処理がなされます。こういう処理ではデータのやりとりにばっかり時間を食っていて、本当の計算時間なんてごく僅かのものだなと感じます。

そういうことで、データー量がそれほど大きくないコード関係は RDB を使うのをやめてメモリーに乗せていこうと思っています。管理も、RDB で管理するよりも、テキストベースにして git で管理した方が遙かに管理しやすいし、入力もデータベース用の入力画面を使うよりも、テキストエディターや Excel で編集できた方が楽です。RDB をやめることの欠点ってといえば、コードを修正する毎にアプリをデプロイしなければいけないので、その手間が増えるのですが、昔と違って今はデプロイが楽になっているのでデータの更新の頻度ににもよりますがそれほどの負担にはならないと思います。

AWS vs Azure vs GCP

2017年2月12日

最近、このサイトを運用しているサーバーを Google Cloud Platform の Google Compute Engine に移転しました。その際に調べたことをメモしておきます。

まず、サーバーで価格を重視するのであれば、VPS がいいと思います。メモリ 1G のものが1000円程度、8G のものが 数千円程度であります。クラウドの場合 CPU だけであれば同じぐらいの価格ですが、ストレージやデータ転送量が別途必要になるので価格は1.3倍とかになってしまいます。ただし、VPS には以下のような欠点があるので、安定した運用向きです、

  • 初期費用が必要だったり月単位の料金のところが多く、柔軟にサーバーの能力や台数を変更することができない。OSやアプリケーションの大規模なバージョンアップの場合、運用を止めないためには平行運用をする時間が必要であるが、クラウドのようにその時間だけの費用ではなく、初期費用等の料金が発生する。
  • クラウドの場合は、バックアップが簡単に取れたり、Amazon S3 のようなクラウドストレージが利用できるが、VPS では、そのようなサービスがない。

クラウドで IaaS を選択する場合には以下の記事が参考になると思います。

クラウドの Iaas 分野では、リーダーは AWS(Amazon Web Servise)です。上に紹介した記事で「AWSは多様な顧客ベースを有し、ほとんどのユースケースを網羅している。」とあるように、サービスの豊富さでは他を圧倒しています。

価格的には、AWS、Azure、Google Cloud Platform(GCP) も割引を除いては大きな差はありません。AWS はサービスが豊富です。AWS の典型的なサービスとしては、Amazon Aurora があり、OSS の RDB である MySQL 及び PostgreSQL をクラウド向けに改良してフルマネージドのサービスとして提供しています。AWS は、ビジネスに必要なツールをクラウドに適した形で提供するというのが得意です。

Azure は、企業のニーズを満たすために重要な機能、例えば、セキュリティ、可用性、ユーザー管理などの機能が充実しています。例えば、バックアップであれば下の図のように、毎日定時にバックアップするとかファイルの回復という機能がついています。自分が以前にExcelで事務をして Windows 2013 Server をファイルサーバーにしていた時にこういうことをしていました。

Azureのバックアップの図

また、料金サービスの面でも以下のように企業向けには便利なものがあります。

  • エンタープライズ契約をして前払いをすると大幅な割引がある。
  • 他のクラウドがクレジットカード払いになるのに対して、エンタープライズ契約をすると請求書払いが可能。また、リセラーからライセンスキーを購入するという方法もあるのでクレジット払いをしなくてもすむ。
  • 料金が円建てなので為替による変動がない。

このようなことから、Azure の売上高は急増しています。しかし、自分のような個人や零細企業の場合は、割引が全く適用されないこと、AWS であればスポットインスタンス、GCP であればプリエンプティブインスタンスに対応するものがないことから、コスト的に相当高くなるので AWS か GCP を選択した方がいいと思います。

GCP(Google Compute Platform)は、記事に「この業界のリーダーに分類されている企業が有している機能に相当するものすべては備えていないため、大企業や中規模企業を強く魅了することに苦労している」とありますが、自分もそのとおりだと思います。そういうことで、利用者数では AWS や Azure から一歩遅れていることも事実です。

しかし、開発者の立場からすると、快適に使えるクラウドです。昨年の11月に東京リージョンが開設されたことだし、$300ドルで60日間使用できるクレジットが貰えるということなので、実際に使ってみました。GCE は、起動が速く、マシンを1分もかからずに起動できます。また、起動しているマシンを止めることなくスナップショットを1分ぐらいで取れます。そのため、運用しているマシンを増やすのも簡単だし、テスト環境も直ぐに作れます。

また、ダッシュボードは下の図のようになっており、管理画面はかなり使いやすいし、AWS と違って料金を払わなくても 1分間隔の CPU の稼働率が表示されるのが嬉しいところです。管理機能は、Stackdriver が使っており、かなり高機能なことができるようです。

GCPのダッシュボードの図

価格的には、AWS とほぼ同じですが、割引の条件が AWS の EC2 場合は1年又は3年縛りになっていて事前に購入が必要等料金設定が複雑です。それに対して、GCE の場合は、1ヶ月単位で長時間使用していれば勝手に割引してくれるのでかなり楽です。

自分なりのクラウドの選択についての結論をいうと以下のようになります。

  • ビジネスのために使いたいのであれば、AWS がベストです。Amazon はECサイトから発展した会社だけあってユーザーニーズを最もよくつかんでいる会社です。だから、今後もサービスの豊富さではリーダーシップを取っていくと思います。
  • エンタープライズであれば、Azure がいいと思います。SQL Server、 Windows Server、Microsoft Office のようにエンタープライズ向けの製品を扱ってきた経験と実績があり、エンタープライズが必要な機能が充実しています。
  • Web、スマートフォンのバックエンド、AI、データサイエンス等の分野で使うのであれば GCP がベストです。GCP は、Google が自社の環境を一般公開しているという側面が強く、基本性能は高いので、このような Google が得意とする分野では優れたものがあります。

自分の場合は、Google Adsense、Analytics、Search Console 等の Google のサービスを以前から使っており、また、以前のブログ「ボットネットの脅威を考えたら Google Cloud を使うのがベストだ」に書いているように、DDoS攻撃に強いものにしていきたいので GCP を選択しました。

Visual Studio 2017 RC を使ってみた

2017年2月2日

Visual Studio 2017 RC のアップデートがあり、「.NET CoreおよびASP.NET Core のワークロードは、もはやプレビュー版ではない。.NET Core およびASP.NET Core の Toolのいくらかのバグを修正し、使いやすさを改善した」ということなので使ってみました。

.NET Core SDK の preview2 までは、プロジェクトファイルが project.json でしたが、Visual Studio 2017 では、MSBuild の .csproj 形式に変更になりました。それがどうなっているか知りたかったためです。

Visual Studio 2017 で project.json 形式のプロジェクトを開こうとすると、以下のように一方向のアップグレードというメッセージがでます。

アップグレードの画像

ここで、「OK」をクリックすると、.csproj 形式に変更されます。それでアップグレードは完了で、動作します。

ただし、このアップグレードは、完全ではないようなので、Project.json と MSBuild の .csproj 形式の対応を調べたい場合は、Hanselman 氏のブログにあったのですが、次の記事が参考になりました。

Project.json to MSBuild conversion guide

Project.json と .csproj のどちらがいいのかという議論はあると思うのですが、.csproj の方もかなり簡単になっているので、.csproj でいいのかなと思います。自分の場合は、今回の変更については問題はなかったです。

このサイトも、アップグレードして Visual Studio 2017 用にしました。Visual Studio 2017 の方は、バグらしきものはまだ残っていますが、Visual Studio 2015 と同じレベルで使えています。

ASP.NET Core アプリを Linux サーバーで公開」のページの方も.csproj 形式の方に更新しました。

統計LODのバグから見える沖縄の歴史

2017年1月18日

統計LODの「統計に用いる標準地域コード」を使っていて面白いバグを見つけたのでメモしておきます。

沖縄県では、北部が本土に近いので国頭(くにがみ)郡で、南部はシマの尻となるので島尻郡です。それにもかかわらず、沖縄県の最も北に位置し東シナ海上に浮かぶ伊平屋村及び伊是名村は国頭郡ではなくて島尻郡に属しています。

伊平屋島は、琉球王朝の第一尚氏縁の地であり、伊是名島は、第二尚氏縁の地です。そのため琉球王朝の時代には直轄地だったという歴史があり、その後の経過を経て島尻郡に属するようになったようです。

具体的な統計 LOD のバグの内容ですが 検索用画面で以下の Query を実行してみてください。

PREFIX rdf:<http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs:<http://www.w3.org/2000/01/rdf-schema#>
PREFIX org:<http://www.w3.org/ns/org#>
PREFIX dcterms:<http://purl.org/dc/terms/>
PREFIX sacs:<http://data.e-stat.go.jp/lod/terms/sacs#>
PREFIX sac:<http://data.e-stat.go.jp/lod/sac/>
PREFIX sace:<http://data.e-stat.go.jp/lod/sace/>
PREFIX sacr:<http://data.e-stat.go.jp/lod/sacr/>

SELECT ?p ?o WHERE { 
  sace:C394 ?p ?o .  
}

Output を Text にすると次のように検索結果が返されます。

-------------------------------------------------------------------------------------------------
| p                         | o                                                                 |
=============================================================================
| rdf:type                  | sacs:CodeChangeEvent                                              |
| org:resultingOrganization | sac:C47361-20020401                                               |
| org:resultingOrganization | sac:C47352-20020401                                               |
| org:resultingOrganization | sac:C47351-20020401                                               |
| dcterms:description       | "Nakazato-son(47351) and Gushikawa-son(47352) are merged, and Kumejima-cho(47361) in Shimajiri-gun is newly established."@en |
| dcterms:description       | "仲里村(47351)、具志川村(47352)が合併し、久米島町(47361)を新設"@ja|
| org:originalOrganization  | sac:C47352-20001222                                               |
| org:originalOrganization  | sac:C47361-19720607                                               |
| org:originalOrganization  | sac:C47351-20001222                                               |
| dcterms:identifier        | "394"                                                             |
| sacs:reasonForChange      | sacr:establishmentOfNewMunicipalityByMmerging                |
| dcterms:date              | "2002-04-01"^^<http://www.w3.org/2001/XMLSchema#date>       |
-------------------------------------------------------------------------------------------------

org:originalOrganization(変更前の期間つき標準地域コードのリソース)に、sac:C47361-19720607 があります。確かに 47361 は現在の久米島町の市町村コードではありますが、1972年には久米島町はなかったはずです。実は C47361-19720607 は、宮古郡城辺町(現宮古市)の昔の市町村コードです。47361 という市町村コードは使い回しされていたのです。

市町村コードは廃止されたコードは欠番とされ、新たなコードとして別の自治体に交付しないという原則に例外があったのです。恐らくそのことを知らないエンジニアが間違ったプログラムを書いたのですが、影響はあまりないのでそのままになっていると思います。

なぜこういうことが発生したのか、まず、1965年(昭和40年)の沖縄県の国勢調査の結果をみてみると、以下の図のように琉球政府の時代には郡は使わずに北部地区という名称を使っていたようです。

1965年の沖縄県の国勢調査のの画像

1970年(昭和45年)の沖縄県の国勢調査の結果をみると、復帰前ですが本土と同じように市町村コードが振られて郡が復活しています。その際に北部地区をそのまま国頭郡にしてしまったようです。

1970年の沖縄県の国勢調査のの画像

本土復帰後になって、伊平屋村及び伊是名村が島尻郡に属していることがわかり修正しようとしたのですが、運悪く島尻郡に属する町村が多すぎて伊是名村が47360というコードになり宮古郡のコードと衝突してしまったのです。それで宮古郡のコードを47370に変更し、宮古郡に属する町村のコードも変更せざるを得なくなったようです。そして、合併で久米島町ができたときに 47361 になり城辺町の昔のコードを使い回してしまったということのようです。

統計LODから取得した標準地域コードを利用して、統計メモ帳のページを追加中なので、完成したらそのページの方も紹介したいと思います。