Hatena::ブログ(Diary)

hnwの日記 このページをアンテナに追加 RSSフィード

[プロフィール]
 

2016年8月28日(日) Language Update PHP編(LLoT補足) このエントリーを含むブックマーク このエントリーのブックマークコメント

昨日8/27にLLoTの「Language Update」の10分枠でPHPの話をしました。発表資料は以下です。



会場にPHPの人はほとんどいない前提だったので、他の言語の人に「最近のPHPってこんな感じですよ」をお伝えするつもりで資料作成しました。言いたかったことはだいたい言えたつもりですが、補足と感想などを書いてみます。


PHP 7.0でのトピック

プレゼン資料にも書いたんですが、PHP 7についてお伝えしたかったことは2点、メジャーバージョンアップながら移行のハードルは低いという点、また高速化チーム(PHPNGチーム)が高速化を達成したことの意義、という2点になります。


メジャーバージョンアップといえばPerl 4→5やPython 2→3の混乱が連想されると思うんですが、それに比べるとPHP 5→7は内部構造のみの大変更であり、他の言語で言えばマイナーバージョンアップと同レベルの変更だと思う、というのは他の言語の方々にも十分伝わったのかなと思います。


また、PHP 7で高速化チームが無事高速化を達成したこと自体はPHPユーザーでなくても知っている内容だったと思うんですが、この意義は大きかったと個人的には考えています。というのは技術面よりも政治面です。


PHPは絶対的なリーダーがものごとを決めるような運営方針ではないため、これまでは横断的な変更をかけにくい雰囲気があったように思います。今回の高速化は既存コード全体に影響するようなものであり、このような大変更の前例が作れたという意味で今後に繋がるものだと感じています。


PHP 7.1でのトピック

今回発表に向けて7.1でのトピックを探したんですが、7.0に比べると劇的な成果とまでは言えないような変更が多い印象を持ちました。


たとえば、PHPプログラム最適化処理(OPcache内の処理)にコンパイラ最適化でよく用いられるSSA静的単一代入形式)を作るような処理が入っていますが、いまのところ全然役に立っていないように見えます。7.2以降での最適化に繋がっていくことを期待したいですね。


PHP 7.1が11月か12月リリースだろう、というのは下記資料が根拠です。いまのところ順調に進んでいますが、多少の波乱は当然あるでしょう。ちょうど今beta3でBC breakがあったとかいう議論をしていたりします。



動的型付けと静的型付け

今回のイベントでは型の話題が多かったような印象を持ちました。


私のプレゼンでも紹介した通り、動的型付け言語であるPHPでもIDE型推論を利用して実行前に型エラーを検出するような仕組みが身近になってきています。PythonJavaScriptについても近いニーズがあるという印象を受けました。


一方で、SwiftC#など昨今のモダンな静的型付け言語では単相型の型推論を取り入れているものが多くあります。静的型付けが好きな人も、自明な型を書かずに済むなら当然書きたくないわけです。


つまり、両方の陣営が近いゴールを目指しており、その共通の道具は型推論なのだと最近考えていましたが、似た認識を持った方が会場には何人もいらしたように感じました。


個人としては、これから型推論を利用した言語がもっと身近になっていき、最終的にF#が世界制覇したら楽しいなぁと妄想しております。


感想など

会場撤収のタイミングで竹迫さんが「このイベントは全員アウェーなのが面白いんですよ」という話をされていて、なるほどなと思いました。私自身アウェーの楽しさを再認識したイベントでした。


目の前の仕事でさえ学ぶことが多すぎる中でアウェーの場に来るというのは多くの人にとってハードルの高いことだと思うんですが、特に若い人にはアウェーの場に積極的に出て行って多くを吸収してほしいと思います。


最後に、運営のみなさまお疲れさまでした。来年以降も若者を引きつけられるような、魅力あるコンテンツ作りを期待しております。

トラックバック - http://d.hatena.ne.jp/hnw/20160828

2016年8月20日(土) multi-prime RSAとは何か このエントリーを含むブックマーク このエントリーのブックマークコメント

RSAは現在主流と言える公開鍵暗号の方式で、SSHHTTPSなど重要プロトコルで利用されています。我々が普段利用しているRSA暗号では2つの巨大素数p,qを生成し、2素数の積nを公開鍵として利用します。万一nが素因数分解されてしまうと秘密鍵を計算で求めることが可能になりますが、nが2048bitであれば2030年くらいまで素因数分解は非現実的だろうと言われています。


ところで、入手したRSA公開鍵に含まれるnの素因数が3個以上だった場合に、対応する秘密鍵は存在するのでしょうか?また、その秘密鍵素因数分解の結果から計算できるのでしょうか?筆者はこの疑問に長らく答えが出せずにいたのですが、RFC3447(PKCS #1)に「multi-prime RSA」として定義されていることを知りました。本稿ではこの multi-prime RSA について紹介します。


RSA暗号の原理

RSA暗号では公開鍵として(n,e)という整数のペアを利用します。nはすでに紹介した通り巨大素数p,qの積です。eは都合の良い固定値(65537など)がよく使われます。


教科書的な秘密鍵としては(n,d)が使われます。ここでのdは次のような性質を持つ値です。


  • 任意のxに対して x^(e*d)=x (mod n) … (1)

このe,d,nを使うと、RSA暗号化処理・復号処理は次のように表せます。


  • 暗号
    • 平文をiとする、ただしi<n
    • 暗号文 c = i^e (mod n)
  • 復号
    • 暗号文 c に対して c^d (mod n)で平文が得られる

このように、秘密鍵に含まれるdさえバレなければ、暗号化に必要なeは公開することができるという仕組みになっています。


このdはオイラー関数φを用いて次のように表すことができます。


  • e*d = 1 (mod φ(n)) … (2)

つまり、eのモジュラ逆数を取ればdが計算できるというわけです。


たとえばn=3*5の場合について考えてみると、e=3,d=3のときに(2)式を満たします。(1)式で実際に試してみましょう。


Prelude> map (\x -> x^(3*3) `mod` 15) [0..14]
[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14]

n未満の全ての平文が復元できていますので、RSAとして正しく機能することがわかります。


multi-prime RSAの実例

さて、実は上記の説明においてnの素因数が2つである必然性はありません。nとして3素数以上の積を使ったRSAをmulti-prime RSAと呼びます。


仮にn=3*5*7=105とすると、e=5,d=29のときに(2)式を満たします。先ほどと同様に(1)式を確認してみましょう。


Prelude> map (\x -> x^(5*29) `mod` 105) [0..104]
[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104]

やはり期待通りに動いています。このように、multi-prime RSAが機能すること自体は間違いありません。


現実の秘密鍵

ところで、先ほど「教科書的な秘密鍵」という説明をしましたが、現実のRSA実装では上の計算をそのまま行うことはありません。我々が普段使っている秘密鍵には次のような値が含まれています。


  • n
  • e
  • d
  • p
  • q
  • d mod (p-1)
  • d mod (q-1)
  • q^-1 mod p

dはnと同じくらいの大きさになるので、暗号文cの復号c^dは重い処理となります。現実の実装ではc^dをマジメに計算する代わりに、中国の剰余定理を利用してc^(d mod (p-1))とc^(d mod (q-1))の計算に変形し、教科書的な実装より4倍高速に計算を行っています。


ちなみに、nが3素数や4素数の積だった場合は中国の剰余定理を利用することで9倍、16倍と高速になっていきます。このように復号処理を軽量化できる点がmulti-prime RSAのメリットになります。


しかし、実際にmulti-prime RSAでの計算量低減メリットを受けるには秘密鍵のフォーマットを変えてd mod (p1-1),d mod (p2-1),…を持っておかなくてはなりません。このようなフォーマットに対応している実装は存在しないように思います[要出典]。


また、素因数の数を増やせば増やしただけ素因数分解による攻撃可能性も増えていきますので、多くすれば良いというものではありません。適用するとしても3素数が現実的だと考えられているようです。


最初の疑問に対する答え

最初の疑問「入手した公開鍵に含まれるnの素因数が3個以上だった場合に、対応する秘密鍵は存在するのでしょうか?また、その秘密鍵素因数分解の結果から計算できるのでしょうか?」に対する答えは以下のようにまとめられるでしょう。


  • 対応する秘密鍵は存在する(eとφ(n)が素である場合に限る)
  • 理屈上の秘密鍵は計算で求められる
  • 既存の実装に適用できるような秘密鍵はおそらく作れない*1

そもそも筆者がこのような疑問を持ったきっかけは、2015年頃にgithub.com上のSSH公開鍵の素因数分解を試みていた際(参照:「江戸前セキュリティ勉強会でgithub.comの弱い鍵を探す話をしました」)に3つ以上の素因数を持つSSH公開鍵がいくつか見つかったためです。これらの公開鍵はおそらくコピペミスで作られてしまったもので、アカウントの持ち主も対応する秘密鍵を持っていないと考えられますが、このような鍵に対しても素因数分解さえできれば攻撃可能だというのは面白い結論だと感じます。


参考URL

*1:と思ったんですが、 http://xrekkusu.hatenablog.jp/entry/2015/08/17/001939 を見ると正しく動作する秘密鍵が作れているようにも見えますね。どういう理屈なんだろ…。

トラックバック - http://d.hatena.ne.jp/hnw/20160820

2016年7月2日(土) PHPのround関数とは一体なんだったのか このエントリーを含むブックマーク このエントリーのブックマークコメント

(7/3 14:05追記)Javaに関する記述について誤認があったので盛大に書き換えました。Java 6、Java 7、Java 8それぞれで実装が変わっていたようです。

(7/13 23:55追記)本記事中ではroundを四捨五入と言い切ってしまっています。これは筆者がC99のroundを基準に考えているためですが、言語によっては偶数丸めになっているround関数も珍しくありません。ご注意ください。


PHPのround関数について、ネット上で次のような記述を見つけました。


PHP

四捨五入の計算を間違える唯一の言語として畏れられていましたが、そのバグは治っているかもしれません(治ってないかもしれません)


主要なプログラミング言語8種をぐったり解説 - 鍋あり谷あり


各言語を面白おかしく紹介する内容とはいえ、ずいぶん雑な理解だなーという印象です。ゆるふわな話だけでPHPdisられ続けるのもどうかと思うので、一連のround関数の話題について僕なりの総括をしてみたいと思います。


以下、こんなあらすじで紹介していきます。


  • PHP以外でも四捨五入関数バグっぽい挙動は珍しくない
    • RubyPythonの四捨五入はエッジケースで間違っていた
    • Javaの四捨五入にはバグなのか仕様なのか微妙なエッジケースがJava 7まで存在していた
    • 四捨五入で小数点以下n位に丸める仕様がそもそも難しい
  • PHPの現在の実装は整数への丸めについては他の言語と同じ
    • 当時話題になったround関数の実装は2009年リリースのPHP 5.3.0でリプレース済

経緯など

元ネタを知らない人向けに経緯を紹介します。


僕が2007年にPHPソースコード中の四捨五入関数の実装に気持ち悪いマジックナンバーを見つけて「PHPの奇妙なround関数」という記事にしたところ、なぜかRubyのまつもとさんの日記に拾われてバズったという事件がありました。


問題になったround関数の実装は率直に言ってやっつけ感あふれるもので、disられても仕方ない内容だったと思います。そもそも僕自身も「PHP気持ち悪いよね、ひどいよね」というつもりで記事を書いたわけです。しかし、非PHPユーザーが安全地帯からPHPを叩くためだけに乗っかってくるのに若干イラっとしたので、「お前らが安全地帯だと思ってる土台も実は脆いんだぜ」と言いたいがために他言語の浮動小数点数周りのバグを探してみました。


そうして調べていく中で、浮動小数点数の四捨五入について何個かエッジケースがあることに気づきました。また、各種プログラミング言語中の人が必ずしも浮動小数点数に詳しくないこともわかってきました*1。まずはround関数のエッジケースと各言語の対応状況について紹介します。


四捨五入のエッジケース1:0.49999999999999994

0.5より小さい倍精度浮動小数点数の中で最大の数が0.49999999999999994です。これを四捨五入すると、なぜか繰り上がって1になってしまう実装があります。



上記記事で紹介した時点では、RubyPythonがそのような実装になっていました。これは四捨五入が「引数が正なら0.5足して小数点以下を切り捨てる」という実装になっている場合に発生します。この問題を回避する実装は「引数が正のとき小数点以下を切り捨てて元の数との差が0.5以上なら1.0を足す」です。いやー浮動小数点数って難しいですね。


四捨五入の挙動がマニュアル通りとは言えない処理系PHP以外にもあった、というのはこの例だけ見ても明らかでしょう。


ちなみに、本件はRubyPythonとも最新版では修正済みとなります(かなり前から修正されているはずですが詳細な時期は把握していません)。


四捨五入のエッジケース2:9007199254740991.0

9007199254740991.0を四捨五入するとなぜか繰り上がって9007199254740992.0になってしまう実装があります。この数は倍精度浮動小数点数仮数部全bitが1であるような数になります。詳細は下記の記事をご覧ください。



これも先ほどの0.49999999999999994と同じく、「引数が正なら0.5足して小数点以下を切り捨てる」という実装のときに問題になる例です。上記記事のタイミングではPythonだけが該当しましたが、その直前くらいまではRubyも同様の実装でした。


もちろん、現在ではPythonの実装も修正されています。


Javaの四捨五入にはバグなのか仕様なのか微妙なエッジケースがJava 7まで存在していた

さて、上記2つのエッジケースについてですが、Java 6のround関数は2つとも間違いっぽい方に丸めます。


public class RoundTest {
    public static void main(String[] args) {
        double d1 = 0.49999999999999994d;
	double d2 = 9007199254740991.0d;
        System.out.println("d1: " + d1); // 0.49999999999999994
	System.out.println("round(d1): " + Math.round(d1)); // Java 6: 1, Java7-8: 0
        System.out.println("d2: " + d2); // 9.007199254740991E15
	System.out.println("round(d2): " + Math.round(d2)); // Java 6-7: 9007199254740992, Java8: 9007199254740991
    }
}

しかし、Java6の挙動はバグとも言い切れません。Java 6のマニュアルには下記のような記述があります。


public static long round(double a)


Returns the closest long to the argument. The result is rounded to an integer by adding 1/2, taking the floor of the result, and casting the result to type long. In other words, the result is equal to the value of the expression:


(long)Math.floor(a + 0.5d)


http://docs.oracle.com/javase/6/docs/api/java/lang/Math.html#round%28double%29


先ほどからイマイチな実装として紹介してきた「0.5足して小数点以下を切り捨てる」が内部実装だと書いてありますので、上の挙動は仕様なのかもしれません。この記述だけでエッジケースの分かるJavaプログラマがどれほどいるかは疑問ですが、文書化されていること自体は素晴らしいと僕は当時から絶賛していました。


ところで、Java 7以降のマニュアルからはこの内部実装に関する記述が消えているようです。トラックバック頂いた記事「JavaのMath.roundがバグっていないと言える可能性について - What will be done tomorrow?」によれば、Java 7で実装が変わったタイミングでマニュアルの記述も変わったということのようです。ただ、このタイミングではd1のみ正しく丸めるようになったようで、d2は繰り上がってしまう実装だったようです。これはマニュアルの記述「the value of the argument rounded to the nearest long value」に反していると言えるでしょう。


Java 8でさらに実装が変わったようで、Java 8からはエッジケース2件とも正しい方向に丸めるようになっています。


本件、OSCPUにも依存すると考えられるので環境によって再現できたりできなかったりあると思いますが、MacOSX環境のOracle JDKでの実験結果を添付しておきます。



四捨五入で小数点以下n位に丸める仕様がそもそも難しい


良い関数の条件の一つに「挙動が直感的である」ということがあるように思います。特に言語の標準関数であれば、長々説明しないと使えないような関数は害の方が多いくらいだと言えるでしょう。


その意味で、round関数小数点以下(n+1)位を四捨五入して小数点以下n位に丸める実装は危険です。n=0のとき、つまり普通の整数への丸めについて言えば2進の浮動小数点数でも0.5や1.5などが誤差無く表現できるので問題とはなりませんが、n>0の場合について言えば四捨五入の境界線(0.05や0.005)も丸まった後の数(0.1や0.01)もピッタリ表現できないため、仕様を言語化すること自体が難しいと言えます。


容易に思いつく実装として、10^n倍して整数への丸めを行って10^nで割るというものがあります。しかし、浮動小数点数を不用意に10^n倍するのは誤差の蓄積を生みやすい処理です。実際、次の例ではRubyPythonが直感に反する結果を返してしまいます。


$ ruby -e 'x=5.015; print x.round(2), "\n";'
5.01
$ python -c 'x=5.015; print round(x, 2),"\n";'
5.01

こうした実装に対する問題点の指摘を3年ほど前に記事にしました。



その後、より良い実装はどのようなものか?という議論に発展してshiroさんの素晴らしい見解を読むことが出来たのは良かったと思っています。



詳細は記事を読んで頂くとして、やはり「2進の浮動小数点数を10進表記で小数点以下n位に丸める関数の直感的な仕様は存在しない」というのが結論かなと思います。


元々のPHPのround関数も、小数点以下n位に丸める挙動を直感的にしようとして失敗してしまったものです。この件から我々が学ぶべきことは採用された実装のまずさについてではなく、小数点以下n位に丸める仕様を採用したという仕様策定段階の失敗についてではないでしょうか。


余談:その後Ruby小数点以下n位に丸める仕様を採用した

ところで、PHPのround関数に関する議論をしていた2007年当時最新だったRuby 1.8系のround関数には小数点以下n位に丸める指定はありませんでした。つまり、PHPのような悩みは無かったことになります。僕としては、その平和な状態を維持して頂きたいと思っていました。


その後、2008年頃にまつもとさんと飲み会で同席させて頂く機会があり、「Rubyのround関数には小数点以下n位に丸める仕様は絶対に入れない方がいいですよ」的な進言をしたように記憶しています。前後の文脈も何もなくお伝えしたのでキョトンとされていたような気もしますが、僕としてもそんなキモい仕様が採用されちゃう言語はPHPくらいだろうと思っていたので、詳細の話をすることもありませんでした。


ところが、その後Ruby 1.9系のround関数小数点以下n位で丸める仕様が入ってくることになります。僕は経緯を追っていませんが、ユーザーの声に抗えなかったんでしょうか。これまで誰も不満なく使っているようならいいんですけど。


現在のPHPのround関数の実装

現在のPHPのround関数の処理は、問題のあった実装がPHP 5.3.0で改善されてから変わっていません。詳細は次の記事で紹介しています。



この頃からPHPの仕様変更に関する議論RFCと呼ばれるWiki文書ベースで行われるようになり、大きい変更は多くの人の目が入るようになりました。また、仕様がきっちりドキュメントとして残るようになったのも大きな利点です。この丸め処理も下記のRFCベースで議論されており、これを読めば誰でも仕様把握できる状態になっています。



ちなみに、新たな丸め処理では整数への丸めは他の言語と完全に同じでケチの付け所はありません。


一方、小数点以下n位に丸める処理は直感的とは言えません。丸め位置を変えながら2回丸めるような処理になっており、一部エッジケースでバグっぽい挙動をするような、ある意味PHPらしい処理になっています。


とはいえ、先ほどから繰り返しているように小数点以下n位に丸める仕様を採用した時点で失敗だというのが個人的見解です。既に紹介した通り他の言語も誤差上等で実装しているわけで、PHPだけが変というのも違う気がします。


そんなわけで、PHP 5.3.0以降のround関数は他の言語と同等と言ってしまって差し支えないでしょう。


ちなみに当時話題になったround関数が実装されていたのはPHP 5.2系ですが、2009年に5.3系がリリースされてリプレースがはじまり、2011年には5.2系のセキュリティサポートが切れている状況です。完全に昔話という感じですね。


おわりに

四捨五入くらい誰でも実装できるって思うでしょ?意外とそうでもないわけですよ。ホントに。

*1:もちろん平均的には詳しい人が多いですし、スーパー詳しい人もたくさんいます

yukobayukoba 2016/07/03 12:08 Javaを試してみたのですが、Java 1.8.0_91, _92 で
WindowsおよびLinux、Oracle JDKおよびOpenJDKで、
Math.round(d2)は9007199254740992ではなく
9007199254740991になります。

「Javaのround関数は2つとも間違いっぽい方に丸めます。」
ではなく、どちらも正しいのではないでしょうか?

hnwhnw 2016/07/03 13:39 失礼しました。こんな細かいところに修正が入る可能性は低いと思い込んでいたので、手元にたまたまインストールされていた1.7.0_80のみで確認しておりました。確かに私の手元もMacOSXでも1.8.0_92では9007199254740991に丸めます。

また、d1が0に丸まるのは元々正しい方向に丸めてますよね。すみません、完全におかしいことを書いていました。

このあたり本文に追記および修正させて頂きます。ご指摘ありがとうございました。

2016年5月22日(日) 勝手にMarkdownプレビューを開くVS Codeのエクステンションを書いた このエントリーを含むブックマーク このエントリーのブックマークコメント

Visual Studio Code(以下VS Code)、みなさん使ってますか?VS CodeはMicrosoftが開発しているオープンソースエディタです。Electronベースという意味ではAtomと似た存在ですが、Atomより軽いという評判を聞いたりします。


私も最近VS Codeを使い始めました。いまのところMarkdown編集専用という状況ではありますが、便利に使っています。それだけでなく、「Auto-open Markdown Preview」というエクステンションを書いて自分好みの挙動になるようにしてみました。本稿ではその顛末について紹介します。


ちなみに作業はすべてMacOSX上で行いましたが、WindowsでもLinuxでも同様だと思います。


作ったもの

今回、「Auto-Open Markdown Preview」というエクステンションを作りました。Markdownファイルを開いた場合に、自動的にプレビュー画面も開くというものです。


Auto-Open Markdown Preview導入前

f:id:hnw:20160522123147g:image


Auto-Open Markdown Preview導入後

f:id:hnw:20160522123148g:image


大した差では無いように見えるかもしれませんが、個人的な感覚としては凄い便利になりました。Markdown編集するときには常にプレビューしたいに決まっているじゃないですか。


もちろん意見には個人差があります。差があるからこそカスタマイズ性が大事だと思うんですよね。


Auto-Open Markdown Previewのインストール

このエクステンションインストールは簡単で、VS Code上で「F1」を押して「>」を消して「ext install auto-open markdown」とタイプすればインストール候補として出てきます。


f:id:hnw:20160522123146g:image


以下、これを実現するまでの流れを紹介します。


VS Codeのエクステンションとは

すでに紹介した通りVS Codeにはエクステンションの仕組みが用意されており、ユーザーの手でエディタ機能を拡張することができます。エクステンションJavaScriptまたはTypeScriptで書くことができますが、TypeScriptで書いている人が大多数のようです。


また、書いたエクステンションVisual Studio Marketplaceに誰でも無料でパブリッシュすることができます。エクステンションパブリッシュすると上で紹介したようにVS Code本体のエクステンション検索機能でインストール候補として表示されますので、多くのユーザーに簡単に使ってもらえるような仕組みになっています。


エクステンションの作成

VS Codeエクステンションを作るための道具はnpmに登録されています。あのMicrosoftがnpmに自社ツールを登録するなんて…と不思議な気持ちになるのは私だけでしょうか。それはさておき、さっそく準備していきましょう。


$ npm install -g yo generator-code
$ yo code

     _-----_
    |       |    .--------------------------.
    |--(o)--|    |   Welcome to the Visual  |
   `---------´   |   Studio Code Extension  |
    ( _´U`_ )    |        generator!        |
    /___A___\    '--------------------------'
     |  ~  |
   __'.___.'__
 ´   `  |° ´ Y `

? What type of extension do you want to create? (Use arrow keys)
> New Extension (TypeScript)
  New Extension (JavaScript)
  New Color Theme
  New Language Support
  New Code Snippets

指示に従って適当に答えていくとエクステンション名のディレクトリが作られ、その下にひな形が生成されます。また、node_modules以下に必要モジュールがnpm installされます。


自動生成直後の状態では、「Hello World」と表示するだけのextensionが作られています。


$ code --disable-extensions .

上記のようにエクステンションディレクトリをVS Codeで開き、「F5」を押せばエクステンションデバッガ上で動作します。この環境では、ブレークポイントを置いたり変数値を確認したりしながらエクステンション開発ができます。


詳しくは下記URLを参照してください。



エクステンションパブリッシュ

上記の環境で開発が一段落したら、まずパッケージングしてみましょう。


$ npm install -g vsce
$ vsce package

このようにnpmでvsceパッケージをインストールしてコマンドを打てばプロジェクトディレクトリに*.vsixファイルが出来ます。これがVSCodeのエクステンションパッケージになります。これをVS Codeでオープンすればパッケージがインストールされます。


$ code vscode-auto-open-markdown-preview-0.0.1.vsix

Marketplaceへのパブリッシュもコマンド一発です。ただし、Visual Studio Team ServicesMicrosoftの無料リポジトリ&イシュートラッキングサービス、以下VSTS)のアカウントと、VSTS上で発行されるアクセストークンが必要です。


$ vsce create-publisher hnw
$ vsce login hnw
$ vsce publish

詳しくは下記URLを参照してください。



まとめ

VS Codeの挙動に不満があったら自分でエクステンションを作れば解決できるかもしれないこと、またVS CodeのエクステンションをMarketplaceに公開するまでのハードルは非常に低いということを紹介しました。まだまだエクステンションまわりは資料が少ないという印象ですが、Microsoftの公開している資料やVS Code自体のソースコードTypeScript部分が多い)があれば何とかなると思います。


皆さんも便利なエクステンションを書いて公開してみてはいかがでしょうか。

トラックバック - http://d.hatena.ne.jp/hnw/20160522

2016年4月30日(土) 新MacBook (12-inch, Early 2016)を買ったので性能比較してみた このエントリーを含むブックマーク このエントリーのブックマークコメント

先日発表された12-inch MacBookの2代目を衝動買いしました。MacBook Air (13-inch, Mid 2012)からの買い替えです。MacBook Airは不満の少ないマシンでしたが、持ち歩いていたら肩こりがひどくなったので、性能が落ちずに物理的に軽くなるならと考えて買い換えてみました。


スペック比較

両方ともBTOなしの上位モデルです。


MacBook Air
(13-inch, Mid 2012)
MacBook
(12-inch, Early 2016)
CPU 2.0GHz Intel Core i7
(最大3.2GHz)
1.2GHz Intel Core m5
(最大2.7GHz)
Memory 4GB 8GB
SSD 256GB 512GB
Weight 1.35kg 0.92kg

ネット上の情報からするとCPU性能も大差ないと判断して買ったのですが、動作周波数だけで見ると圧倒的に負けているのがわかります。


コンパイル時間でベンチマークテスト

さて、本当に両者の性能に差はないのでしょうか?ベンチマークテスト上は互角でも、体感値とは違う可能性も考えられますので、自分の身近な作業の速度で比較してみたいところです。


というわけで、PHP 7.0.6のビルド時間を測ってみることにしました*1。makeのオプションを-j1と-j4と試してみて、1並列と4並列の場合で比較しました。


MacBook Air
(13-inch, Mid 2012)
MacBook
(12-inch, Early 2016)
相対性能
1並列 12分8秒 11分15秒 +7.3%
4並列 6分44秒 6分30秒 +3.5%


ギリギリですが、新MacBookの方が速いという結果になりました。この程度の差だと条件が少し変わるだけで逆転されそうですが、互角程度であるという点では間違いなさそうです。


上の結果からCPU単体の速い遅いの判断はできません。大物ソフトウェアコンパイル・リンクではディスクI/O性能の差もかなり効いてきます。SSDの性能は新MacBookの方が断然上なので、その差が結果に出ている可能性もありそうです。


1並列より4並列のときの方が両者の差が縮まっている理由としては、新MacBookCPUが過負荷に弱いということが考えられます。IntelTurbo Boostは温度やその他に余裕があるときにオーバークロックする技術なので、ファンレスで動いている新MacBookの方が早く頭打ちが来ても不思議はありません。


実際、他のベンチマーク結果を見ても1コア性能は互角、マルチコア性能は若干落ちる程度のようです。


とはいえ、CPUの動作周波数だけ見ると勝ち目がなさそうに見えたのが、身近な作業で互角かそれ以上の性能だったことに少し安心しました。


参考URL


まとめ

  • MacBook Air (13-inch, Mid 2012) と MacBook (12-inch, Early 2016)の性能は大差なさそう
  • 430gの軽量化に払う金額としては高すぎると思う
    • でも肩こりがツラかったので仕方ない(自分への言い訳)

*1:「phpenv install 7.0.6」の実行時間を比較したので、xdebugその他のビルド時間も含まれています

トラックバック - http://d.hatena.ne.jp/hnw/20160430
 
ページビュー
1917189