Warum ist (point-min) viel beliebter als 1?

16

Ich habe über alle Emacs Lisp-Dateien in Emacs Git repo gesucht und festgestellt, dass sie (goto-char (point-min))3621-mal und (goto-char 1)31-mal vorkommen. Persönlich sehe ich viele, (point-min)aber keine 1, auch in vielen Fällen ist 100% sicher, dass die Region nicht eingeengt ist. Also hier ist meine frage: ist (point-min)noch vorzuziehen, 1auch in nicht eingeengtem puffer?

Ich denke, es 1ist schneller als (point-min), egal wie gering es ist, weil 1es konstant ist, während (point-min)es ein Funktionsaufruf ist. Außerdem 1ist viel kürzer als (point-min)1 Zeichen gegen 11 Zeichen.

xuchunyang
quelle
2
Können Sie ein Beispiel nennen, in dem "es zu 100% sicher ist, dass die Region nicht eingegrenzt wird"? Ich denke, Sie meinen unmittelbar nach der Erweiterung? Sind das wirklich "viele Fälle"?
Omar,
1
Ich dachte immer, der Puffer beginnt um 0 ...
Omair Majid

Antworten:

28

Woher wissen Sie, dass der Puffer nicht verengt ist?

Sie können nicht sicher sein, ob Sie die Funktion direkt vor dem Aufruf erweitert haben. Darüber hinaus wird "großartige Software" häufig als "in einer Weise verwendet, wie der Autor es sich nie vorgestellt hat" definiert. Daher sollte man immer auf die ungewöhnliche Verwendung des eigenen Codes vorbereitet sein.

Die Lesbarkeit des Codes ist König

Wenn Sie schreiben (goto-char 1), wird die Person, die den Code liest (einschließlich Sie 6 Monate später), wertvolle Denkarbeit leisten

  • "Woher wissen wir, dass der Puffer nicht verengt ist?" und
  • "Ist das erste Zeichen 0 oder 1?"

Grundsätzlich (widen)benötigen Sie einen Kommentar, der erklärt, warum Sie sicher sind, dass der Puffer nicht eingegrenzt wird, es sei denn, Sie haben direkt zuvor.

Kosten sind trivial

Eine sichere Annahme ist, dass die Kosten hier geringfügig sind, es sei denn, Sie haben Ihr Code-Profil erstellt und etwas anderes festgestellt. Im Vergleich zu all den anderen Dingen, die ELisp macht (Netzwerk, Festplattenzugriff, sogar String-Matching), (point-min)wird dies keine bedeutenden Kosten verursachen (und möglicherweise sogar billiger sein , siehe Stefans Antwort).

sds
quelle
2
+1, insbesondere zur Hervorhebung einer möglichen Verwendung auf unerwartete Weise und einer möglichen Wiederverwendung in anderen Kontexten. Eine Funktion, die verwendet point-minwird , ist in der Regel allgemeiner als eine, die verwendet wird. 1Sie kann in der Regel unabhängig davon funktionieren, ob die Region eingegrenzt ist oder nicht.
Drew
19

Die Antwort von sds (der ich voll und ganz zustimme) zu ergänzen, (point-min)kann trotz des Auftretens effizienter sein als 1. In Bezug auf die Ausführungsgeschwindigkeit sehen meine Tests keinen messbaren Unterschied, aber in Bezug auf die Größe:

ELISP> (byte-compile '(lambda () (goto-char (point-min))))
#[nil "eb\207" [] 1]

ELISP> (byte-compile '(lambda () (goto-char 1)))
#[nil "\300b\207" [1] 1]

ELISP> 

Das liegt daran, dass point-mines einen eigenen Bytecode hat und daher im Vergleich zu anderen Funktionsaufrufen sehr effizient codiert und ausgeführt wird.

Ein weiterer Grund für mich point-minist natürlich, dass ich die historische Wahl für 1einen Fehler halte (Puffer sollten bei 0 beginnen).

Stefan
quelle
1
Der Grund, den Sie angeben, ist nur, dass der Byte-Code für point-minetwas kleiner ist? Scheint ein ziemlich dürftiger Grund zu sein. Warum darauf Wert legen? Oder war Ihre Antwort wirklich als Kommentar gedacht , um nur die Annahme zu korrigieren, dass einer performanter ist als der andere oder dass 1sich ein kleinerer Byte-Code ergibt?
Drew