2010/04/15

MacBookPro新モデル

このエントリーをはてなブックマークに追加
iPad(とiPhoneOS4)で持ちきりのところ、待望の新モデル。4/13に入れ替わってました。
詳細スペックは、方々で出てます。

GIZMODO -【速報】Core iシリーズ搭載のMacBook Pro発売開始!
http://www.gizmodo.jp/2010/04/core_imacbook_pro.html

CNET JAPAN - アップル、MacBook Proをアップデート--13インチモデルは最長10時間のバッテリ寿命に
http://japan.cnet.com/news/tech/story/0,2000056025,20412054,00.htm

CNET JAPAN - 新MacBook Proはどう変わったか--4つのポイントと新機能
http://japan.cnet.com/news/tech/story/0,2000056025,20412120,00.htm

とりあえず3点。
グラフィック強化がうれしい。
とりあえずグラフィックが強化されたのがうれしいです。
あとスペックアップ強化してるにも関わらず、バッテリー駆動時間が約1.5倍。
強化といってどこまで、動くかどうかは知らないけれど、ゲーミングノートにしたい。

まだCore2Duoを引っ張る。
2010年はモバイルノートはCore i3/i5/i7に染まるっていうもっぱらの噂だったわけですが、MacBookPro(13インチ)に限っては残されてしまうわけですね。
少なくとも、価格的に不満のあるものではないので、最新のCPUとトレードオフで割高感がアップされても困る。
13インチは、ほぼ同スペックだったユニボディの白いMacBookと比較して、ようやく抜きん出たというだけかな。でもこれも、すぐ追いつかれそうで、あまり指標にはなりません。
今年もう一回Core2Duoを払拭するマイナーチェンジがあるのか? さあ、はたして、そんな二度手間みたいなことをするかな?

モデル別の価格差の微妙な具合が気になる。
毎度のことです。
たとえば13インチに限っては、下位と上位、CPU2.4GhzとHDD250GBが、2.66Ghz/320GBという二箇所しか違わないのに、価格は24,000円も違う。性能的にはほとんど変わらないので、これは割高。実質、4モデルくらいかと。どうせならさらなるハイスペックを選択できるようにしてほしかった。
13インチの躯体の手ごろさは魅力だからなあ。これ以上小さくなるとiPadと競合するんでしょうか。


ということで、プライベートでもMacデビューするかな。

2010/04/06

[javascript]canvas、drawImageの機能の違いによる速度の影響を調べる

このエントリーをはてなブックマークに追加
drawImageは、canvasで画像を使用するためのメソッドです。
パラメータがいろいろあるので、機能の違いから、速度にどのくらい影響するのかを調べてみました。

●drawImageの使い方


使い方は、下記を参照してください。
解りやすい解説があります。

Mozilla Developer Center > Canvas チュートリアル > 画像を使う
https://developer.mozilla.org/ja/Canvas_tutorial/Using_images


一度画像をImageオブジェクトに読み込ませないといけないところは他のグラフィック要素と違って面倒ではありますよね。

●処理時間の計測方法


ベースとなるサイズを320px×480pxとし、50%、100%(原寸)、150%、200%にした画像を用意する。
用意した画像について、下記の4パターンをテストしてみます。
  • ①same:画像を伸縮させて320px×480pxに収まるように配置する

  • ②half:画像を伸縮させて160px×240pxに収まるように配置する

  • ③pick:画像を50%切り出したものを伸縮させて、320px×480pxに収まるように配置する

  • ④fixed:画像を320px×480px切り出したものを、320px×480pxに収まるように配置する


上記それぞれの処理を100回繰り返し使用した時間を計測しました。なお、画像の読み込み時間は処理時間には含みません。
パラメータ次第でいろいろな結果がでそうではあるし、ローカル環境のスペックに依存するので数値に信頼性はありません。ざっくり傾向が分析できればよいぐらいの気持ちでお願いします。

●結果


Y軸の単位はmsです。
ChromeとFireFoxで行いました。


極端な結果になりました。しめたものです。
突出しているところは、処理が重いことを示しています。
なお、グラフになる前の数値データは、テストコードと一緒に後に載せます。

●考察


考察します。
結果から言えること。
  • Chromeは画像の一部を抜粋して伸縮する処理(③pickの処理)がネック。抜粋だけで、伸縮がなければ速度は十分出ている。Chromeの③の結果がなければ、全体的にFFよりも圧倒しています。

  • 小さい画像を扱うほうが処理速度は速い。まあ当然。ただし、Chromeに限っては、あまり倍率の異なる伸縮処理は重くなる。

  • FFは、伸縮処理が加わるとと途端に重くなる。処理速度は元の画像サイズに関わらず、配置後の画像サイズに比例している。

  • 共通していえるのは、伸縮処理は重いということ。元のサイズと、配置サイズを一致させるだけで、処理速度は全然違う。

  • 一番速度がでていたのは、Chromeにて実寸を50%のサイズにして配置する処理(100%の②halfの処理)。100回繰り返しで3ms。


ぐりぐりと触れて、再描画を繰り返さないといけない処理は、伸縮機能を使用しないように工夫するべきだという結果に。

●テストコード


function onLoad()
{
var container = document.getElementById("container");
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var srcList = ["img_050.png", "img_100.png", "img_150.png", "img_200.png"];
var funcList = [ function (img)
{
ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, 320, 480);
},
function (img)
{
ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, 160, 240);
},
function (img)
{
ctx.drawImage(img, 0, 0, img.width * 0.5, img.height * 0.5, 0, 0, 320, 480);
},
function (img)
{
if (img.width >= 320 && img.height >= 480) {
ctx.drawImage(img, 0, 0, 320, 480, 0, 0, 320, 480);
}
} ];
// 画像を全部読み込む
var imageList = [];
var loadImage = function (src)
{
var img = document.createElement("img");
img.onload = function ()
{
imageList.push(img);
// next
if (srcList.length > 0) {
loadImage(srcList.shift());
}
else {
loadedImage();
}
};
img.src = src;
img.alt = src;
};
loadImage(srcList.shift());
// 画像が全て読み込まれた後に呼び出される
var loadedImage = function ()
{
for (var i = 0; i < funcList.length; i++)
{
var func = funcList[i];
document.write("<p>");
document.write("<b>" + func + "</b><br>");
for (var j = 0; j < imageList.length; j++) {
var img = imageList[j];
test(img, func);
}
document.write("</p>");
}
};
var test = function (img, func)
{
var now = new Date();
for (var i = 0; i < 100; i++) {
func(img);
}
var stamp = new Date() - now;
document.write(img.alt + "=" + stamp + "<br>");
};
}


処理結果。
・Google Chrome4.1
function (img){ ctx.drawImage(img,0,0,img.width,img.height,0,0,320,480); }
img_050.png=25
img_100.png=18
img_150.png=38
img_200.png=50

function (img){ ctx.drawImage(img,0,0,img.width,img.height,0,0,160,240); }
img_050.png=5
img_100.png=3
img_150.png=21
img_200.png=32

function (img){ ctx.drawImage(img,0,0,img.width * 0.5,img.height * 0.5,0,0,320,480); }
img_050.png=271
img_100.png=1067
img_150.png=1491
img_200.png=18

function (img){ if(img.width >= 320 && img.height >=480){ ctx.drawImage(img,0,0,320,480,0,0,320,480); } }
img_050.png=0
img_100.png=19
img_150.png=18
img_200.png=18

・FireFox3.6
function (img) { ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, 320, 480); }
img_050.png=633
img_100.png=20
img_150.png=639
img_200.png=650

function (img) { ctx.drawImage(img, 0, 0, img.width, img.height, 0, 0, 160, 240); }
img_050.png=13
img_100.png=192
img_150.png=191
img_200.png=191

function (img) { ctx.drawImage(img, 0, 0, img.width * 0.5, img.height * 0.5, 0, 0, 320, 480); }
img_050.png=632
img_100.png=642
img_150.png=643
img_200.png=20

function (img) { if (img.width >= 320 && img.height >= 480) { ctx.drawImage(img, 0, 0, 320, 480, 0, 0, 320, 480); } }
img_050.png=0
img_100.png=20
img_150.png=20
img_200.png=20

2010/04/02

[javascript]true or false

このエントリーをはてなブックマークに追加
// ①
if (value) {
// 処理
}

// ②
if (value == true) {
// 処理
}

ある日ふと、上記①②の結果が異なることに気づく。
勝手にキャストされるんでしょ?と横柄にも思っていたけれど、どうもそうではないらしい。
当たり前だけど、数値⇔文字が自由に行き来するからといって、全ての型がそういうわけでもないのです。

どういう挙動なのだろうと不信に思ってしまったので、いろんな型の判定について調べてみる。
対象とするのは、undefined、null、数値(1、123、0、NaN)、文字("abc"、"1"、"123"、"0"、"")、日付、論理値(true、false)、オブジェクト型、配列、関数です。

テスト結果。


まとめ


  • 前述の通り、if(value)と(value==true)は結果が異なる。一致させるためには、Boolean(value)を使って明示的にキャストする必要がある。

  • if(value)がfalseになるのは、null、undefined、0、NaN、""、falseのとき。これは基本。

  • テスト内容とは関係ないけれどtypeof(null)はobjectになる。nullはobject。

  • (value == null)がtrueになるのは、null、undefinedのみ。

  • (value == true)と(value == 1)が一緒。

  • (value == false)と(value == 0)が一緒。(value == "")はvalue="0"のとき以外は一緒。

  • (value == true)と(value != false)は一致するとは限らない。true/falseと1/0などの論理値以外はあやしい。

  • 文字列の"true"は、Booleanとして自動的にキャストされたりしない。通常の文字列と同じ扱い。

  • 文字列の"0"は、数値にキャストされて、(value==false)と(value==0)にtrueを返す。(この辺がややこしい)

  • 配列が空かどうかが(value == false)で判別できる。if(value)は配列数に限らずtrueになる。

  • isNaNの挙動もよくわからん。objectや関数でtrueになるのはなんだろう。


論理値の挙動については、いまいち感覚的に理解しにくい印象です。
型の指定がないのをいいことに、混在させまくる利用は、コードが煩雑になることが避けられない気がします。やっぱりきっちり管理したほうが楽かも。

テストコード


以下、テストに使ったコードのベース。
実際はtrueになったところに色をつける処理を足しています。
var undef;
// undefined;
var list =
{
_undefined : undef, _null : null, _int_1 : 1, _int_123 : 123, _int_0 : 0, _nan : Number.NaN, _str_abc : "abc",
_str_1 : "1", _str_123 : "123", _str_0 : "0", _str_null : "", _str_true : "true", _bool_true : true,
_bool_false : false, _obj : {}, _array_null : [], _array_1 : [1], _func : function () {}
}
document.write("<table>");
document.write("<tr>");
document.write("<th>key</th>");
document.write("<th>typeof(value)</th>");
document.write("<th>value</th>");
document.write("<th>if(value)</th>");
document.write("<th>Boolean(value)</th>");
document.write("<th>value==true</th>");
document.write("<th>value==false</th>");
document.write("<th>value==1</th>");
document.write("<th>value==0</th>");
document.write("<th>value==null</th>");
document.write("<th>value==\"\"</th>");
document.write("<th>isNaN(value)</th>");
document.write("</tr>");
for (var key in list)
{
var value = list[key];
var r = false;
if (value) {
r = true;
}
document.write("<tr>");
document.write("<td>" + key + "</td>");
document.write("<td>" + (typeof (value)) + "</td>");
document.write("<td>" + value + "</td>");
document.write("<td>" + r + "</td>");
document.write("<td>" + Boolean(value) + "</td>");
document.write("<td>" + (value == true) + "</td>");
document.write("<td>" + (value == false) + "</td>");
document.write("<td>" + (value == 1) + "</td>");
document.write("<td>" + (value == 0) + "</td>");
document.write("<td>" + (value == null) + "</td>");
document.write("<td>" + (value == "") + "</td>");
document.write("<td>" + (isNaN(value)) + "</td>");
document.write("</tr>");
}
document.write("</table>");