0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

TypeScript 7.0 はコンパイラが Go に書き直され「最大10倍速くなる」と言われています。
同じプロジェクトで実際に計測したところ、今回の実験では 5.6倍 の差が出ました。
プロジェクト規模・型の複雑さによってはさらに差が広がります(公式ベンチでは最大11倍)。

結果

左(TS 6.0.3)がまだコンパイル中のうちに、右(TS 7.0.2)は完了しています。

ts7比較.gif

フェーズ TS 6.0.3 TS 7.0.2 倍率
Parse 0.80s 0.271s 3.0x
Bind 1.08s 0.089s 12.1x
Check 7.51s 1.338s 5.6x
Total 9.61s 1.716s 5.6x
Memory 2,366MB 1,389MB -41%
壁時計 10秒 2秒 5倍

計測方法

ファイル生成スクリプト(generate.js)

generate.js を実行すると src/ 配下に 3,002 個の TypeScript ファイルが生成されます。

const fs = require('fs');
const path = require('path');

const SRC_DIR = path.join(__dirname, 'src');
const NUM_MODULES = 3000;

fs.readdirSync(SRC_DIR).forEach(f => fs.unlinkSync(path.join(SRC_DIR, f)));

// エンティティ定義(User / Product / Order をローテーション)
const ENTITY_DEFS = [
  {
    name: 'User',
    fields: ['id: string', 'email: string', 'name: string', 'roles: string[]', ...],
    events: "'user.created' | 'user.updated' | 'user.deleted'",
  },
  // Product, Order も同様
];

for (let i = 0; i < NUM_MODULES; i++) {
  const entity = ENTITY_DEFS[i % ENTITY_DEFS.length];
  const content = generateModuleCode(entity, i); // 後述
  fs.writeFileSync(path.join(SRC_DIR, `module_${String(i).padStart(3, '0')}.ts`), content);
}

// src/index.ts:全モジュールを re-export
let index = '';
for (let i = 0; i < NUM_MODULES; i++) {
  index += `export * from './module_${String(i).padStart(3, '0')}';\n`;
}
fs.writeFileSync(path.join(SRC_DIR, 'index.ts'), index);

生成されるコード(module_001.ts の例・抜粋)

DeepReadonly / StateMachine / InferFromSchema など複雑なジェネリクスを組み合わせた型が 1 ファイルあたり約 200 行生成されます。

import type {
  DeepReadonly, DeepPartial, DeepRequired,
  PathsOf, StateMachine, TypedEmitter,
  InferFromSchema, ExtractRouteParams, Prettify,
} from './types';

export interface Product1 {
  id: string;
  sku: string;
  price: number;
  images: { url: string; alt: string; position: number }[];
  variants: { id: string; sku: string; price: number; stock: number }[];
  attributes: Record<string, string | number | boolean>;
}

export type ReadOnlyProduct1 = Prettify<DeepReadonly<Product1>>;
export type PartialProduct1  = Prettify<DeepPartial<Product1>>;

// 配布型 × 条件型の組み合わせ
export type ProductFilterOps1<T> =
  | { eq: T } | { neq: T } | { in: T[] }
  | (T extends number ? { gt: T } | { between: [T, T] } : never)
  | (T extends string ? { contains: T } | { matches: string } : never);

export type ProductWhereClause1 = {
  [K in keyof Product1]?: ProductFilterOps1<Product1[K]>;
} & { AND?: ProductWhereClause1[]; OR?: ProductWhereClause1[] };

// JSON スキーマ → 型推論
type ProductMetaSchema1 = {
  type: 'object';
  properties: {
    version: { type: 'number' };
    tags: { type: 'array'; items: { type: 'string' } };
  };
  required: ['version'];
};
export type ProductMeta1 = Prettify<InferFromSchema<ProductMetaSchema1>>;

// State Machine 型
export type ProductMachine1 = StateMachine<
  'idle' | 'fetching' | 'success' | 'error',
  'FETCH' | 'RESOLVE' | 'REJECT' | 'RESET',
  { data: Product1 | null; error: string | null }
>;

// Service クラス(型推論の負荷になる)
export class ProductService1 {
  constructor(private readonly repo: ProductRepository1) {}

  async create(data: Omit<Product1, 'id'>): Promise<Product1> {
    return this.repo.create(data);
  }
  async update(id: string, data: PartialProduct1): Promise<Product1 | null> {
    return this.repo.update(id, data);
  }
}

ベンチマーク Shell スクリプト

bench_ts6.sh(TS 7.0.2 版は bench_ts7.sh、パスと色だけ異なります):

#!/usr/bin/env bash

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TSC="$SCRIPT_DIR/node_modules/.bin/tsc"  # TS 6.0.3

clear
echo "TypeScript 6.0.3 コンパイルベンチマーク"
echo "⏳ コンパイル中..."

START_SEC=$SECONDS
DIAG=$("$TSC" -p "$SCRIPT_DIR/tsconfig.json" --extendedDiagnostics 2>&1)
ELAPSED=$(( SECONDS - START_SEC ))

# 各フェーズの時間を表示
echo "$DIAG" | grep -E "^(Files|Symbols|Types|Instantiations|Memory used|Parse time|Bind time|Check time|Total time)"

echo "完了! 経過時間: ${ELAPSED}秒"

インストール

npm install --save-dev typescript@6.0.3
npm install --save-dev typescript@7.0.2 --prefix node_ts7
node generate.js

実行(2 つのターミナルで同時に)

./bench_ts6.sh   # ターミナル1
./bench_ts7.sh   # ターミナル2(先に終わります)

おわりに

今回は、TypeScript7.0のコンパイル速度について紹介しました!!1年以上待ち侘びたリリースだったので、非常に嬉しいです!!みなさんも7.0の凄さを体験してみてください!!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?