Khanh Hoang - Kenn
Kenn is a user experience designer and front end developer who enjoys creating beautiful and usable web and mobile experiences.
Trong phần 1, mình đã giới thiệu tới mọi người tính năng thứ nhất của XDebug đó là debug code PHP. XDebug không chỉ dừng lại mỗi tính năng này, cái hay của nó là ở phần Profiler website - tính năng rất hữu ích cho việc tìm ra bottle-neck (nút thắt cổ chai) của website, từ đó đưa ra giải pháp cải tiến, nâng cấp, tối ưu nhầm mang lại hiểu quả cao hơn cho website. Hôm nay mình sẽ chia sẻ 1 phần kỹ thuật này, giúp mọi người có thể tự tay tìm ra điểm "chậm" của website mình
Cũng như phần 1, chúng ta cần tùy chỉnh đôi điều trong tập tin php.ini, tìm đến vị trị bạn đã từng cấu hình Xdebug trước đây và thêm vào đoạn bên dưới (Xem lại phần 1 để biết cách mở file php.ini với WAMP).
xdebug.profiler_enable = Off xdebug.profiler_enable_trigger = On xdebug.profiler_output_name = callgrind.out.%t.%p xdebug.profiler_output_dir = "d:/wamp/profiler" xdebug.collect_params = On xdebug.show_local_vars = On
Với cấu hình bên trên, có nghĩa là tính năng profiler của XDebug mặc định sẽ được tắt, và bạn phải kích hoạt bằng tay thì nó mới bắt đầu tính profiler. Sau khi profiler xong, nó sẽ được lưu vào thư mục D:/wamp/profiler với tên bắt đầu là callgrind.out (Có thể xem thêm link sau để biết cách cấu hình mở rộng của Xdebug với profiler -http://xdebug.org/docs/profiler ). Như vậy khi cần chạy profiler, bạn sẽ gõ thêm trên trình duyệt 1 biến dạng $_GET hoặc $_POST như sau XDEBUG_PROFILE
Sau khi profiler thì XDebug sẽ phát sinh một tập tin có cấu trúc, và chúng ta cần 1 trong số những công cụ để có thể đọc được kết quả profiler này.
Trong bài viết này, mình sẽ dùng KCacheGrind để làm minh họa cho việc profiler
Ở ví dụ này, mình dùng 1 bài toán nhỏ trên database có mô hình ERD như bên dưới.
ERD demo profiler website
Tiếp theo, mình viết 2 class tương tác với 2 table trong ERD như bên dưới.
class Article dùng tương tác với table articles trong DB. Có một phương thức là lấy bài viết theo tác giả
Class Author dùng tương tác table authors trong DB. Có phương thức lấy thông tin tác giả.
Tiếp theo là mình viết 1 script nhỏ để test vấn đề tương tác DB như sau
script sử dụng 2 class Author và Article. Hiển thị kết quả ra màn hình.
Và kết quả như sau:
Kết quả khi chạy script bên trên
Dưới đây là kết quả profiler cho đoạn script bên trên. Để chạy được profiler như cấu hình bên trên này, các bạn thêm vào trình duyệt biến $_GET XDEBUG_PROFILE. Ví dụ file mình chạy là http://localhost/test.php thì thêm vào đó là http://localhost/test.php?XDEBUG_PROFILE. Sau đó chúng ta dùng KCacheGrind để xem kết quả như hình bên dưới.
Kết quả profiler lần 1
Với ví dụ đơn giản trên, thì tác giả được lấy đến 3 lần mặc dù là cùng 1 người (author_id không thay đổi) dẫn tới việc profiler thông báo hàm Author->getDetailAuthor được gọi đến 3 lần. Chúng ta cải thiện lại 1 chút cho class Article như sau:
Thay đổi logic code ở class Article
Kết quả vẫn sẽ như cũ, tuy nhiên lúc này xem profiler thì hàm Author->getAuthorDetail chỉ còn 1 lần như bên dưới.
Kết quả profiler lần 2
Tuy nhiên, chúng ta vẫn có thể cải tiến thêm tí nữa để tăng performance cho website như sau
Và kết quả là trong đây chúng ta không còn gọi tới class Author cũng như gọi các hàm của class này. Kết quả profiler như sau:
Kết quả profiler lần 3
Cùng nhìn lại kết quả 3 lần profiler để xem chúng ta đã làm được những gì so với việc cải tiến 2 lần như trên. Chúng ta sẽ nhìn thấy rằng với lần số 3, code chúng ta thực hiện ít hàm hơn nhiều, nhưng thời gian thực thi cao hơn. Chuyện gì xảy ra vậy? Chẳng gì cả, đó là do chúng ta dùng cấu trúc JOIN trong câu lệnh SQL nên đã làm chậm lại đáng kể. Tuy nhiên, hãy cải tiến thêm lần nữa bằng việc cache lại kết quả câu SQL, lần này bạn sẽ thấy hoàn toàn khác. Nhưng phần này thì mình sẽ để mọi người tự khám phá vậy
Kết quả 3 lần profiler