perf: filter discovery tokenizes the app and system `Config/Filters.php` on every request
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 72/100
- Loại issue
- Tái cấu trúc
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- php
- Lĩnh vực
- backend, performance
Hướng nghiên cứu
Bắt đầu từ phương thức private discoverFilters(), được gọi từ constructor của Filters, và xem cách kết quả của FileLocator::search() được truyền vào getClassname(). Thêm một kiểm tra để bỏ qua các đường dẫn APPPATH và SYSTEMPATH Config/Filters.php trước lệnh gọi đó, giữ nguyên các đường dẫn khác. Chạy tests/system/Filters/FiltersTest.php; hoàn thành khi một locator giả lập (spy) được chèn qua Services::injectMock('locator', ...) không cho thấy lệnh gọi getClassname() nào đối với các tệp của ứng dụng hoặc hệ thống, và bộ lọc tùy chỉnh trong tests/_support cùng alias test-customfilter của nó vẫn hoạt động.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Problem
Filters::__construct() calls the deprecated discoverFilters() on every request when filter discovery is on, which it is by default. That method finds every Config/Filters.php across all namespaces. For each file, it calls FileLocator::getClassname(), which runs file_get_contents() and token_get_all() on the file.
In a default app, discovery finds only two files:
app/Config/Filters.phpsystem/Config/Filters.php
Both get read and tokenized, and then both are skipped, because their class is Config\Filters or CodeIgniter\Config\Filters. So every request pays to parse two files it never uses.
Measurements
PHP 8.3 on macOS, OPcache on, production mode, warm. Each number is averaged over 300 runs.
| Case | Time |
|---|---|
new Filters(...), discovery on (default) |
~103 µs |
new Filters(...), discovery off |
~0.2 µs |
FileLocator::search('Config/Filters.php') |
~15 µs |
FileLocator::getClassname() per file |
~42 µs |
For a full request to a bare closure route, Services::filters() is about 126 µs. That's the largest single cost left once #10615 lands, at about 14–18% of the request.
Proposal
In discoverFilters(), compare each found path against APPPATH . 'Config/Filters.php' and SYSTEMPATH . 'Config/Filters.php' before calling getClassname(). Skip those two paths with no file read.
FileLocator::search()already returns real paths, andAPPPATHandSYSTEMPATHare real paths too, so a plain string compare works.- Every other file keeps today's class-name check, unchanged. Module and package discovery files are still included as they are now.
With the default setup, the cost drops to the search() call alone, about 15 µs.
Compatibility
- No public or protected API changes.
discoverFilters()is private. - There's one edge case. Today, if
app/Config/Filters.phpdeclared some class other thanConfig\Filters, discovery wouldincludeit. After this change, that file is skipped. This layout breaks the framework's own conventions, and filter discovery has been deprecated since 4.4.2. So no changelog or upgrade-guide entry is planned.
Tests
Add a regression test in tests/system/Filters/FiltersTest.php. It uses a spy FileLocator, injected with Services::injectMock('locator', ...), that records the paths passed to getClassname(). The test asserts that:
getClassname()is never called for the app or systemConfig/Filters.php.getClassname()is still called fortests/_support/Config/Filters.php, and thetest-customfilteralias it adds is still registered.
The existing discovery test (FiltersTest.php:488) keeps covering the third-party path.
Related
- #10615. It covers config construction cost. This issue is independent and can land separately.
- Ngôn ngữ chính
- PHP
- Star
- 6k
- Fork
- 2k
- Merge trung bình
- 1 ngày 22 giờ
- Pull request đã merge (30 ngày)
- 59
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- 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.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của codeigniter4/CodeIgniter4
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 35/100
codeigniter4/CodeIgniter4#10618 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 62/100
codeigniter4/CodeIgniter4#10617 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 25/100
codeigniter4/CodeIgniter4#10615 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
bug
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 48/100
codeigniter4/CodeIgniter4#10589 · 3 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
dev
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 25/100
codeigniter4/CodeIgniter4#10427 · 5 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của codeigniter4/CodeIgniter4
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
scanaislop/aislop#482 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
Maintainer thường phản hồi trong vòng 1 ngày
-
documentation
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
humanmade/publication-checklist#73 · 1 bình luận ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
Werkstattl/OpenBlogware#92 ·