スタックマシン
レジスタマシンでは、同じ式の値を複数回使用する場合に、それを1回だけ計算して結果をレジスタに保持しておき、再利用することができる。スタックマシンで同じことをしようとすると、2つの方法が考えられる。1つは、共通部分式の計算結果をメモリ上の一時変数にセーブする方法である。しかし、これは共通部分式が単なるメモリ上の変数の参照などだった場合、全く最適化になっておらず、ある程度複雑な式でないと効果を生じない。そしてプログラマは複雑な式の結果をソースコード上で局所変数に格納し、何度も同じ式を書くことはしないのが一般的である。2つめは、共通部分式の計算結果をスタック上に残し、それを必要なだけ複製して利用する方法である。これは、"DUP"、"ROT"、"OVER" といったスタック操作を行ってもスタックがそれほど深くならない場合には効果的である。仮想スタックマシンの中には、"PICK" という命令でスタック内の指定した位置の値をスタックトップに複製する機能を持つものもある。Forthなどで書かれたプログラムはこのような技法を多用していることが多く、結果としてレジスタマシン並みの性能を達成している。しかし、スタック・スケジューリングの最適化アルゴリズムは一般に知られておらず、スタックマシンを意識しない通常の言語でそのような最適化を行うことは難しい。結果としてスタックマシン向けコンパイラでは共通部分式除去などの最適化は行われていない。
レジスタマシンと異なりオペランドを指定する領域が命令内に存在しないため、命令の読み出し・デコードと並行して、その命令が使用するオペランドの読み出しを行うことが出来る。加えて、明示的なロード命令を用いない限り、スタック内のオペランドが使われる順序は、スタックトップから下方へ積まれている順序と一致する。このため、スタックトップから優先してレジスタファイルなどにキャッシュされた状態を保つだけで、オペランドの強力なプリフェッチが実現される。さらに、各命令のオペランドが取り出される場所はスタックトップ数個の範囲内に絞られるため、このスタックトップ数個をキャッシュする代わりに命令パイプライン内のフォアワーディング回路に流すことで、レジスタファイルへのアクセスを命令パイプラインの実行ステージ以前のステージから排除できる。このようにレジスタマシンと比較して命令パイプラインの長さを短く出来るため、より高い動作周波数、または、より少ない遅延スロットを実現できる。
仮想マシンの場合でも、この性質は有用である。ハードウェアでのフォアワーディング回路の代わりに、スタックトップをレジスタにキャッシュする実装が広く行われており、メモリロード遅延の影響が抑えられている。レジスタマシンを仮想マシンで実装する場合、多くのホストマシンでは実行時にレジスタを番号で参照することができないため、番号で参照するならメモリ配列を用いる方が単純かつ高速となる。また、仮想マシンの管理用にホストマシンのレジスタが消費されるため、ターゲットマシンのレジスタの全てを実装するにはホストマシンのレジスタが足りなくなる事もある。このため、ターゲットマシンのレジスタを実装するのにホストマシンのメモリ領域が使われる事が多い。