eval-when-compile: defsubst vs defmacro vs notify-inline


8

Tôi đã định nghĩa một số hàm đơn giản trong init.el, ví dụ my-cache-file:

(defconst my-cache-directory
  (expand-file-name ".cache" user-emacs-directory)) ; ~/.emacs/.cache

(defun my-cache-file (x)
  (expand-file-name x my-cache-directory))          ; ~/.emacs/.cache/x

(setq savehist-file
      (my-cache-file "savehist"))

(setq backup-directory-alist
      `(("." . ,(my-cache-file "backups/"))))

Đây có vẻ như là một trường hợp sử dụng tốt cho defsubst:

(defsubst my-cache-file (x) ...)

Sau đó, tôi bắt đầu học về biên dịch, và muốn tối ưu hóa hơn nữa. Tôi ngây thơ cố gắng:

(defsubst my-cache-file (x)
  (eval-when-compile (expand-file-name x my-cache-directory)))

nhưng trình biên dịch đã phàn nàn (đúng) về biến miễn phí x, vì vậy thay vào đó tôi gói mã gọi:

(setq savehist-file
      (eval-when-compile (my-cache-file "savehist")))

(setq backup-directory-alist
      `(("." . ,((eval-when-compile (my-cache-file "backups/"))))

Tuy nhiên, người gọi cuối cùng có lẽ nên đánh giá toàn bộ thời gian biên dịch, vì vậy tôi đã kéo eval-when-compilelên:

(setq backup-directory-alist
      (eval-when-compile `(("." . ,(my-cache-file "backups/")))))

Tôi muốn tránh xả rác mã của mình với nhiều eval-when-compilecuộc gọi hơn mức cần thiết và tôi tự hỏi liệu có cách tiếp cận nào tốt hơn tôi có thể sử dụng macro hay không define-inline. Các tài liệu làm cho define-inlineâm thanh đầy hứa hẹn:

Các hàm được xác định thông qua định nghĩa nội tuyến có một số lợi thế đối với các macro được xác định bởi defsubst hoặc defmacro:

  • Chúng có thể được truyền cho mapcar (xem Chức năng ánh xạ).
  • Họ hiệu quả hơn.
  • Chúng có thể được sử dụng làm biểu mẫu địa điểm để lưu trữ các giá trị (xem Biến tổng quát).
  • Chúng hoạt động theo cách dễ dự đoán hơn cl-defsubst (xem Danh sách đối số trong Phần mở rộng Lisp chung cho GNU Emacs Lisp).

Nhưng cú pháp có vẻ rườm rà và tôi không thể tìm thấy một ví dụ nào về việc nó được sử dụng ngoài tự nhiên. Tôi cũng không thể tìm thấy bất kỳ lời giải thích nào về tuyên bố rằng defsubst kém hiệu quả hơn.

Có ai đã sử dụng define-inline, hoặc có một macro khác mà tôi nên xem xét, hoặc tôi chỉ nên gắn bó với defsubst?

Câu trả lời:


6

Tôi muốn nói rằng hãy gắn bó với defun.

Nếu bạn muốn thử define-inline, cái mới (thậm chí nó chưa có chuỗi doc!), Hãy tiếp tục.

Nhưng hãy nghĩ về bao nhiêu bạn muốn hoặc cần nội tuyến. Rất hiếm khi cần nó, IMO (chắc chắn không phải cho các loại điều bạn thể hiện ở đây, nhưng họ không nghi ngờ gì chỉ để có được câu hỏi trên).

Tôi chắc chắn sẽ khuyên bạn không nên sử dụng defsubst. Bạn có thể không cần nó, và nó chỉ cản trở bạn. Nó có thể đã có một trường hợp sử dụng vào năm 1985, nhưng tôi biết không có nơi nào hữu ích bây giờ. define-inlinerõ ràng là một nỗ lực để có được lợi ích defsubstmà không có nhược điểm.

Câu hỏi này có thể chủ yếu dựa trên ý kiến. Câu trả lời này chỉ là một ý kiến, trong mọi trường hợp.


Câu trả lời tốt, cảm ơn bạn! Bạn nói đúng, tôi đã chọn một ví dụ đơn giản chủ yếu là vì sự rõ ràng. Tôi tò mò muốn thử một defmacrohoặc define-inlinegiải pháp, vì vậy tôi có thể sẽ mất một đâm vào họ. Nó sẽ được tốt đẹp để eval-when-compilenướng vào biểu thức kết quả.
ivan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.