microsoft / microsoft/TypeScript

Proposal: Flatten the AST to speed up tsgo

Đang mở
#63,807 5 bình luận 1 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Possible Improvement
Ngôn ngữ chính
Go
Star
111k
Fork
14.3k
Merge trung bình
2 ngày 4 giờ
Pull request đã merge (30 ngày)
132

Mô tả

We may be able to improve `tsgo` performance by changing the AST representation from a pointer-based tree to a flat array.

## Problem

More than 20% of tsgo’s execution time is spent in GC, so optimizing GC should make it run faster.
For example, when running against the VSCode repository with `GOGC=off`, execution becomes 1.24 times faster:

| Repository | default (s) | GOGC=off (s) | Ratio | Command |
| ---------- | ----------- | ------------ | ------------------------ | ------------------------------- |
| VSCode | 6.567 | 5.292 | 1.24 ± 0.11 times faster | npm run compile-check-ts-native |

According to `pprof`, most of the GC time is spent scanning objects, and the parser AST accounts for about 50% of `inuse_space`. This suggests that reducing the scan cost of the AST could reduce GC time.

## Proposed solution

I propose adopting a flat AST. Flattening an AST means [converting its tree data structure into a simple slice](https://www.cs.cornell.edu/~asampson/blog/flattening.html).

As background, Go’s garbage collector [does not scan the backing array of a slice](https://go.dev/wiki/CompilerOptimizations#non-scannable-objects) when the slice element type contains no pointers. This optimization can eliminate the scan cost of large arrays.

If we can apply this to the AST, we should be able to reduce the amount of memory scanned during each GC cycle, which could reduce GC time.

As a first step, we could remove pointers from the `Node` struct like this:

```
type Arena struct {
Node []Node
Data []nodeData // still contains 2 pointers because of interface boxing
}

type NodeId uint32

type Node struct {
Parent NodeId // replace the parent pointer
Kind Kind
Flags NodeFlags
Loc core.TextRange
}
```

This would reduce the number of pointers in the AST and allow scanning to be skipped for `[]Node`.

Note that `nodeData` still contains pointers. It may be possible to optimize this further by making `Arena` hold separate arrays for each type.

## Trade-offs

Pros:

- Better locality, which may improve CPU cache efficiency
- Pointer-free `Node`

Cons:

- Less intuitive API
- More complex dynamic updates and deletion in arrays

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Hướng nghiên cứu

Issue không nêu tên tệp hay test nào; hãy bắt đầu bằng cách profiling tsgo với pprof và so sánh lệnh VSCode npm run compile-check-ts-native khi dùng GC mặc định và GOGC=off. Đọc kỹ biểu diễn Arena, Node, NodeId và nodeData được đề xuất. Được xem là hoàn tất khi có một thiết kế AST phẳng đã được xác thực cùng các cải thiện đo được về GC hoặc thời gian thực thi, nhưng chưa có mục tiêu nghiệm thu nào được chỉ định.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
go
Lĩnh vực
compilers, performance
Loại issue
Tái cấu trúc
Độ khó
5/5
Thời gian dự kiến
Hơn một tuần
Mức độ hoạt động
Ít trao đổi
Độ rõ ràng
Cần làm rõ
Mức phù hợp với người mới
25/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.