M1 Mac について調べたことあれこれ

この3連休にゆっくり情報収集していたら、M1 Mac がとても欲しくなってしまった。買うなら今使ってる MacBook Pro 13-inch の同モデルへの買い替えかな。

とはいえ Homebrew 動かないとか、そういった情報もあり、開発用に簡単に使うには少しハードルがまだある模様。Rosetta 2 を使えばなんとかなるのかな?とも思うけど使用感がわからない。現状そこまで困っていないので、しばらく様子見。

M1 と Apple Silicon について

  • Apple は Aシリーズと名付けた自社製 Soc(Apple Silicon)を iPhone、iPad、Apple Watch、Apple TV などに搭載してきた。Aシリーズを Mac 向けに強化したのが M1。
  • SoC は「System on a chip」の略で、CPU、GPU、メモリなどの集積回路を1つのパッケージで実現したチップ。モバイルなどの小さなデバイスは大体このチップを使って作られている。
  • ARM はコアのアーキテクチャの一種で、それを使って各社 SoC を実装しており、Apple Silicon もこのアーキテクチャを採用している。
  • M1 は 5nm プロセスを採用した初の PC 向けチップで、160 億個のトランジスタを搭載。

M1 Mac について

  • すべて Big Sur (macOS 11) 搭載。
  • MacBook Air はファンレスでタッチバーなし。MacBook Pro はファンありの冷却システムを持つ分ピーク性能が上。

アプリについて

  • Intel プロセッサ向けバイナリと Apple Silicon 向けバイナリを1つのパッケージでまとめた「Universal Apps」と、Intel プロセッサ向けバイナリを M1 Mac で動作させる「Rosetta 2」を提供。
  • iOS 向けのアプリが、M1 Mac では直接動作するようになる。

References

PHP FPM のチューニング

このサイトはNginx + WordPress で運用しているだが、設置当初はサイトが重くて仕方なかった。
top コマンドで状況を調べてみるとメモリを使い切っていたので、途方に暮れて解決策をググったところ、以下の記事を発見。 有用な記事をありがとうございました。

CentOS php-fpmの設定を変更してメモリ消費を減らした方法 | CrystalSnowman.com

サーバーはさくらのVPS (Cent OS 6、メモリ 1GB) なので、この記事とまさに同じ状況らしい。 これを参考に PHP FPM の設定 (/etc/php-fpm.d/www.conf) を以下のように変更し、現状運用中。

pm = dynamic
pm.max_children = 10 ; default 50
pm.start_servers = 5
pm.min_spare_servers = 2 ; default 5
pm.max_spare_servers = 6 ; default 35

設定変更前と比較にならないくらい軽く(というか普通に)なった。ここのようにアクセス数の少ないサイトはこういった設定で問題ないらしい。

PHP FPM はデフォルトで最大50ものプロセスを立ち上げようとするということは、比較的ハイスペックな環境を想定して設計されているのだろうか。果たして。

[React.js] setStateしても直ちにstateは変更されない

最近仕事でReactをやっている。
今回のネタはひとこと(ひとコード?)で言うと以下のようなこと。

getInitialState () {
  return { clicked: false };
},
clickHandler () {
  this.setState({ clicked: true });
  console.log(this.state.clicked); // -> false
},
render () {
  console.log(this.state.clicked); // -> true
  return <button onClick={this.clickHandler}>Click Me</button>;
}

インタラクションのハンドラで this.setState したとして、そのハンドラ内でthis.state を参照しても、まだ更新後の値は取れない。render() が呼ばれるタイミングでは更新後の値になっている。実際にステートが更新されるタイミングは意図的に制御されているらしい。トリッキーだ。

更新後の値は変数に入れておいて this.setState しつつ、ハンドラ内ではその変数の値を使うのがおそらく正解だろう。

getInitialState () {
  return { clicked: false };
},
clickHandler () {
  var value = true;
  this.setState({ clicked: value });
  console.log(value); // -> true
},
render () {
  console.log(this.state.clicked); // -> true
  return <button onClick={this.clickHandler}>Click Me</button>;
}

Chrome 43 からは DOM attribute が prototype プロパティに変更される

DOM Attributes now on the prototype chain

それによって…

  • hasOwnProperty()/getOwnPropertyDescriptor()/JSON.stringify() で、DOM attribute が検出できなくなる
  • read-only な DOM attribute を上書きしようとすると例外を投げるようになる

だそうな。
他人が作ったフレームワークは特に、それで動かなくなったりするものも出てくるかもしれないので頭の片隅に置いておくとよい。

Maxのドキュメントを読む その2(Javascript in Max 02 – Basic Techniques)

JavaScript in Max ドキュメントの日本語備忘録的なエントリー第2弾。

Global Methods

Document

以下のメソッドはグローバルコンテキストにあり、どこでも使うことができる。


messnamed (Max object name, message name, any arguments)

Document

グローバルシンボルに紐付けてネーミングされた Max オブジェクトにメッセージを送る。例えば receive オブジェクトなど。 以下の例は “jsmessage” と名付けられたオブジェクトに “hogehoge” とメッセージを送る例である。

Test Code

function loadbang () {
    messnamed("jsmessage", "hogehoge");
}

messnamed


cpost (any arguments)

Document

コンソールにメッセージを出力する。引数とかは次項の post() と同じ。

Test Code

function foo(a, b, c) {
  cpost(a, b, c);
}
function loadbang() {
  foo('foo', [ 'a', 'b', 'c' ], { 'hoge': 'fuga' });
}

How Input to the js Object is Handled


なお、グローバルスコープは jsthis オブジェクト(ブラウザ JavaScript でいうwindow オブジェクト)とドキュメントには書いてあるが、jsthisオブジェクトを呼び出そうとしてもMAXウィンドウに Javascript ReferenceErrod: jsthis is not defined と出て怒られる。 一方、一般的な this オブジェクトは機能している。

function foo() { }
post(this.foo === foo); // 1 (true)

post (any arguments)

Document

MAXウィンドウにメッセージを出力する。 \n を含めると改行になる。 post() を新しい行から初めても改行が出力される。

Test Code

function foo(a, b, c) {
  post(a, b, c);
}
function loadbang() {
  foo('bar', [ 'a', 'b', 'c' ], { 'hoge': 'fuga' });
}

How Input to the js Object is Handled


The jsthis Object

Document

Browser JavaScript だと ”window” にあたるもの。 jsthis オブジェクトはグローバルコードにおける ”this” を表す。グローバルコードで関数を定義すればそれは jsthis のメソッドになり、変数を定義すれば jsthis のメソッドになる。jsthis オブジェクトは以下のようなビルトインプロパティとメソッドを持つ。

autowatch (Number, get/set)

Document

これはとりわけ、1つのソースファイルからいくつかの js インスタンスを作っていて、ソースファイルを変更したらすべてのインスタンスを更新したいような時に便利。外部のテキストエディタでソースファイルを書いている場合も、これを使えばパッチ中の js オブジェクトは自動的に再コンパイルされる。 デフォルトではこの autowatch は 0 (off) に設定されている。on にしたいときはグローバルコード中で行うことがベスト。

box (Maxobj, get)

Document

js オブジェクトを含む Maxobj を返す。jsui オブジェクトからオブジェクトボックスの長方形を取得する際に便利。 詳しくは the Max Object を参照のこと

editfontsize (Number, get/set)

Document スクリプトを編集するウィンドウのフォントサイズを制御する。グローバルコードで書くと、テキスト編集のデフォルトフォントサイズ(Maxウィンドウのフォントサイズ)が変更される。

inlet (Number, get)

Document 関数の実行中、 inlet プロパティには、その関数を呼び出したメッセージを受け取ったインレット番号が格納されている。 この番号は一番左のインレットから0で始まる。 グローバルコード中ではこのプロパティは 0 になる。

inlets (Number, get/set)

Document インスタンスがいくつのインレットを持つべきかを指定する。”inlets” プロパティはグローバルコード中で指定しなければ効果がない。指定されなかった場合、インレットを1つ持ったオブジェクトが作られる。

Test Code 1

function msg_int(a) { // a == 1
  post(a); // 1
}

msg_int

Test Code 2

function msg_int(a) { // a == 1
  post(a); // 1
}
function msg_float(a) { // a == 1.23456
  post(a); // 1.23
}

msg_float


list

Document

inlet に最初の値が int もしくは float の list が入力されると list() が呼ばれる。 上記の例のように最初の値が String の list はその String 名の関数が呼ばれる。

Test Code 1

function list(a, b, c) { // a == 1, b == 2, c == hoge
  post(a, b, c); // 1 2 hoge
  post(arguments.length); // 3
}

list


anything

inlet に入力されたものに該当する function が定義されていなかった場合、anything() で受け取ることができる。例えば int が入力されたときに msg_int() が未定義だったら anything() が呼ばれる。float や list でも同様。
anything() 内部では messagenameinlet 変数が定義されており、それぞれ inlet に入ったメッセージの種類と、inlet 番号を参照できる。

Test Code 1

function anything(a, b, c) { // a == 1, b == 2, c == hoge
  post("messagename", messagename); // messagename list
  post("inlet", inlet); // inlet 0
  post("anything", a, b, c); // anything 1 2 hoge
}

anything


loadbang

Document

loadbang() はパッチ起動時に呼ばれる。js オブジェクトや jsui オブジェクトを追加した時ではなく、あくまでそれを予め含むパッチ起動時に呼ばれることに注意。
Cmd+Shiftを押しながらパッチを起動すると loadbang を無効化できるが、無効になっているかどうかは max.loadbangdisabled プロパティに 1 が入っているかどうかで分かる。

Test Code 1

function loadbang() {
  if (max.loadbangdisabled == 1) {
    post("no loadbang");
  } else {
    post("loadbang!");
  }
}
function bang() {
  post("bang!");
}

普通にパッチを起動した場合
loadbang

Cmd+Shiftを押しながらパッチを起動した場合
noloadbang


getvalueof

Document

JavaScript 内で定義した変数の値(String か Number)を pattr 関連オブジェクトから呼び出せるようにする関数。 → pattr オブジェクトのことがよく分からないので、テストコードが書けない。後で復習する。


setvalueof

Document

pattr 関連オブジェクトから JavaScript 内に変数(Number か String)をパスできるインターフェースを提供する関数。 value が複数の場合、jsthis オブジェクトの arrayfromargs() メソッドで引数を扱うと良いとのこと。
→ pattr オブジェクトのことがよく分からないので、テストコードが書けない。後で復習する。


save

Document

save() を定義すると、JavaScript 内の状態をパッチに保持することができる。 パッチが再読み込みされると、JavaScript 内の状態が復元される。

save() 内だけで使える embedmessage() を使い、値を保存する。

  • embedmessage() の第1引数には保存された値を渡したいコールバック関数名を文字列で渡す
  • embedmessage() の第2引数以降には保存したい値を渡し、これがコールバック関数の引数に渡される

Test Code 1

var valuetosave = 0;
function foo(v) {
  valuetosave = v;
}
function save() {
  embedmessage("callback", valuetosave);
}
function callback(v) {
  valuetosave = v;
  post(v);
}

foo 1 メッセージを送ったあと、パッチを再起動した場合
save

foo 2 メッセージを送ったあと、パッチを再起動した場合
save


notifydeleted

Document

js オブジェクトが削除されたときに呼ばれる

Test Code 1

function notifydeleted() {
  post('js object was deleted.');
}

notifydeleted


Global Code

Document

グローバルスコープに書かれたコードは編集された後、スクリプトがロードされるかコンパイルされたタイミングで評価される。 js / jsui オブジェクトが完全に作られる前に評価される。 js オブジェクトがいくつ inlet / outlet を持つかはグローバルコードからは分からない。これはグローバルコードから inlet / outlet をいくつにするか定義できることを意味する。しかし言い換えれば、まだ outlet が存在しなければ、使うことはできない。 初期化処理を書きたい場合は loadbang() の中に書くべし。

グローバルコードでやるべきこと

  • inlet / outlet の数を定義する
  • jsarguments[] プロパティ(js オブジェクトの引数)にアクセスする
  • inlet / outlet の値の操作
  • グローバル変数の定義と初期化
  • グローバルアプリケーション環境にアクセス&操作するため、Max オブジェクトを使う

グローバルコードでやるべきでないこと

  • outlet から何か出力すること
  • js オブジェクトが置かれたパッチ側を参照しようとすること

Private (Local) Function

Document

js オブジェクトへの inlet メッセージから参照されたくないローカル関数を作りたい場合、local プロパティに 1 をセットする。

Test Code 1

function foo() {
  post("Welcome to 'foo' method!");
}
foo.local = 1;

private function


未完