1297 lines
36 KiB
HTML
1297 lines
36 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<!-- 2022-12-15 Thu 21:42 +06 -->
|
|
<meta charset="utf-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<title>Emacs Lisp is Probably Faster Than What You Think | Akib Azmain Turja</title>
|
|
<meta name="author" content="Akib Azmain Turja" />
|
|
<meta name="generator" content="Org Mode" />
|
|
<style>
|
|
#content { max-width: 60em; margin: auto; }
|
|
.title { text-align: center;
|
|
margin-bottom: .2em; }
|
|
.subtitle { text-align: center;
|
|
font-size: medium;
|
|
font-weight: bold;
|
|
margin-top:0; }
|
|
.todo { font-family: monospace; color: red; }
|
|
.done { font-family: monospace; color: green; }
|
|
.priority { font-family: monospace; color: orange; }
|
|
.tag { background-color: #eee; font-family: monospace;
|
|
padding: 2px; font-size: 80%; font-weight: normal; }
|
|
.timestamp { color: #bebebe; }
|
|
.timestamp-kwd { color: #5f9ea0; }
|
|
.org-right { margin-left: auto; margin-right: 0px; text-align: right; }
|
|
.org-left { margin-left: 0px; margin-right: auto; text-align: left; }
|
|
.org-center { margin-left: auto; margin-right: auto; text-align: center; }
|
|
.underline { text-decoration: underline; }
|
|
#postamble p, #preamble p { font-size: 90%; margin: .2em; }
|
|
p.verse { margin-left: 3%; }
|
|
pre {
|
|
border: 1px solid #e6e6e6;
|
|
border-radius: 3px;
|
|
background-color: #f2f2f2;
|
|
padding: 8pt;
|
|
font-family: monospace;
|
|
overflow: auto;
|
|
margin: 1.2em;
|
|
}
|
|
pre.src {
|
|
position: relative;
|
|
overflow: auto;
|
|
}
|
|
pre.src:before {
|
|
display: none;
|
|
position: absolute;
|
|
top: -8px;
|
|
right: 12px;
|
|
padding: 3px;
|
|
color: #555;
|
|
background-color: #f2f2f299;
|
|
}
|
|
pre.src:hover:before { display: inline; margin-top: 14px;}
|
|
/* Languages per Org manual */
|
|
pre.src-asymptote:before { content: 'Asymptote'; }
|
|
pre.src-awk:before { content: 'Awk'; }
|
|
pre.src-authinfo::before { content: 'Authinfo'; }
|
|
pre.src-C:before { content: 'C'; }
|
|
/* pre.src-C++ doesn't work in CSS */
|
|
pre.src-clojure:before { content: 'Clojure'; }
|
|
pre.src-css:before { content: 'CSS'; }
|
|
pre.src-D:before { content: 'D'; }
|
|
pre.src-ditaa:before { content: 'ditaa'; }
|
|
pre.src-dot:before { content: 'Graphviz'; }
|
|
pre.src-calc:before { content: 'Emacs Calc'; }
|
|
pre.src-emacs-lisp:before { content: 'Emacs Lisp'; }
|
|
pre.src-fortran:before { content: 'Fortran'; }
|
|
pre.src-gnuplot:before { content: 'gnuplot'; }
|
|
pre.src-haskell:before { content: 'Haskell'; }
|
|
pre.src-hledger:before { content: 'hledger'; }
|
|
pre.src-java:before { content: 'Java'; }
|
|
pre.src-js:before { content: 'Javascript'; }
|
|
pre.src-latex:before { content: 'LaTeX'; }
|
|
pre.src-ledger:before { content: 'Ledger'; }
|
|
pre.src-lisp:before { content: 'Lisp'; }
|
|
pre.src-lilypond:before { content: 'Lilypond'; }
|
|
pre.src-lua:before { content: 'Lua'; }
|
|
pre.src-matlab:before { content: 'MATLAB'; }
|
|
pre.src-mscgen:before { content: 'Mscgen'; }
|
|
pre.src-ocaml:before { content: 'Objective Caml'; }
|
|
pre.src-octave:before { content: 'Octave'; }
|
|
pre.src-org:before { content: 'Org mode'; }
|
|
pre.src-oz:before { content: 'OZ'; }
|
|
pre.src-plantuml:before { content: 'Plantuml'; }
|
|
pre.src-processing:before { content: 'Processing.js'; }
|
|
pre.src-python:before { content: 'Python'; }
|
|
pre.src-R:before { content: 'R'; }
|
|
pre.src-ruby:before { content: 'Ruby'; }
|
|
pre.src-sass:before { content: 'Sass'; }
|
|
pre.src-scheme:before { content: 'Scheme'; }
|
|
pre.src-screen:before { content: 'Gnu Screen'; }
|
|
pre.src-sed:before { content: 'Sed'; }
|
|
pre.src-sh:before { content: 'shell'; }
|
|
pre.src-sql:before { content: 'SQL'; }
|
|
pre.src-sqlite:before { content: 'SQLite'; }
|
|
/* additional languages in org.el's org-babel-load-languages alist */
|
|
pre.src-forth:before { content: 'Forth'; }
|
|
pre.src-io:before { content: 'IO'; }
|
|
pre.src-J:before { content: 'J'; }
|
|
pre.src-makefile:before { content: 'Makefile'; }
|
|
pre.src-maxima:before { content: 'Maxima'; }
|
|
pre.src-perl:before { content: 'Perl'; }
|
|
pre.src-picolisp:before { content: 'Pico Lisp'; }
|
|
pre.src-scala:before { content: 'Scala'; }
|
|
pre.src-shell:before { content: 'Shell Script'; }
|
|
pre.src-ebnf2ps:before { content: 'ebfn2ps'; }
|
|
/* additional language identifiers per "defun org-babel-execute"
|
|
in ob-*.el */
|
|
pre.src-cpp:before { content: 'C++'; }
|
|
pre.src-abc:before { content: 'ABC'; }
|
|
pre.src-coq:before { content: 'Coq'; }
|
|
pre.src-groovy:before { content: 'Groovy'; }
|
|
/* additional language identifiers from org-babel-shell-names in
|
|
ob-shell.el: ob-shell is the only babel language using a lambda to put
|
|
the execution function name together. */
|
|
pre.src-bash:before { content: 'bash'; }
|
|
pre.src-csh:before { content: 'csh'; }
|
|
pre.src-ash:before { content: 'ash'; }
|
|
pre.src-dash:before { content: 'dash'; }
|
|
pre.src-ksh:before { content: 'ksh'; }
|
|
pre.src-mksh:before { content: 'mksh'; }
|
|
pre.src-posh:before { content: 'posh'; }
|
|
/* Additional Emacs modes also supported by the LaTeX listings package */
|
|
pre.src-ada:before { content: 'Ada'; }
|
|
pre.src-asm:before { content: 'Assembler'; }
|
|
pre.src-caml:before { content: 'Caml'; }
|
|
pre.src-delphi:before { content: 'Delphi'; }
|
|
pre.src-html:before { content: 'HTML'; }
|
|
pre.src-idl:before { content: 'IDL'; }
|
|
pre.src-mercury:before { content: 'Mercury'; }
|
|
pre.src-metapost:before { content: 'MetaPost'; }
|
|
pre.src-modula-2:before { content: 'Modula-2'; }
|
|
pre.src-pascal:before { content: 'Pascal'; }
|
|
pre.src-ps:before { content: 'PostScript'; }
|
|
pre.src-prolog:before { content: 'Prolog'; }
|
|
pre.src-simula:before { content: 'Simula'; }
|
|
pre.src-tcl:before { content: 'tcl'; }
|
|
pre.src-tex:before { content: 'TeX'; }
|
|
pre.src-plain-tex:before { content: 'Plain TeX'; }
|
|
pre.src-verilog:before { content: 'Verilog'; }
|
|
pre.src-vhdl:before { content: 'VHDL'; }
|
|
pre.src-xml:before { content: 'XML'; }
|
|
pre.src-nxml:before { content: 'XML'; }
|
|
/* add a generic configuration mode; LaTeX export needs an additional
|
|
(add-to-list 'org-latex-listings-langs '(conf " ")) in .emacs */
|
|
pre.src-conf:before { content: 'Configuration File'; }
|
|
|
|
table { border-collapse:collapse; }
|
|
caption.t-above { caption-side: top; }
|
|
caption.t-bottom { caption-side: bottom; }
|
|
td, th { vertical-align:top; }
|
|
th.org-right { text-align: center; }
|
|
th.org-left { text-align: center; }
|
|
th.org-center { text-align: center; }
|
|
td.org-right { text-align: right; }
|
|
td.org-left { text-align: left; }
|
|
td.org-center { text-align: center; }
|
|
dt { font-weight: bold; }
|
|
.footpara { display: inline; }
|
|
.footdef { margin-bottom: 1em; }
|
|
.figure { padding: 1em; }
|
|
.figure p { text-align: center; }
|
|
.equation-container {
|
|
display: table;
|
|
text-align: center;
|
|
width: 100%;
|
|
}
|
|
.equation {
|
|
vertical-align: middle;
|
|
}
|
|
.equation-label {
|
|
display: table-cell;
|
|
text-align: right;
|
|
vertical-align: middle;
|
|
}
|
|
.inlinetask {
|
|
padding: 10px;
|
|
border: 2px solid gray;
|
|
margin: 10px;
|
|
background: #ffffcc;
|
|
}
|
|
#org-div-home-and-up
|
|
{ text-align: right; font-size: 70%; white-space: nowrap; }
|
|
textarea { overflow-x: auto; }
|
|
.linenr { font-size: smaller }
|
|
.code-highlighted { background-color: #ffff00; }
|
|
.org-info-js_info-navigation { border-style: none; }
|
|
#org-info-js_console-label
|
|
{ font-size: 10px; font-weight: bold; white-space: nowrap; }
|
|
.org-info-js_search-highlight
|
|
{ background-color: #ffff00; color: #000000; font-weight: bold; }
|
|
.org-svg { }
|
|
</style>
|
|
<style>
|
|
body { font-size: 110%; }
|
|
#preamble { max-width: 54rem; margin-top: auto; margin-bottom: auto;
|
|
margin-left: auto; margin-right: auto; }
|
|
#content { max-width: 54rem; margin-top: auto; margin-bottom: auto;
|
|
margin-left: auto; margin-right: auto; }
|
|
.title { text-align: left; }
|
|
.subtitle { text-align: left; }
|
|
.timestamp { color: #333333; font-size: 0.9em; }
|
|
.footer { font-size: 80%; line-height: 1.5em; }
|
|
#postamble { max-width: 54rem; margin-top: auto; margin-bottom: auto;
|
|
margin-left: auto; margin-right: auto; }
|
|
</style><link rel="me" href="https://hostux.social/@akib"/>
|
|
<!-- CSS generated from `default' theme. -->
|
|
<style type="text/css">
|
|
<!--
|
|
.org-ansi-color-black {
|
|
/* ansi-color-black */
|
|
color: #000000;
|
|
background-color: #000000;
|
|
}
|
|
.org-ansi-color-blue {
|
|
/* ansi-color-blue */
|
|
color: #0000ee;
|
|
background-color: #0000ee;
|
|
}
|
|
.org-ansi-color-bold {
|
|
/* ansi-color-bold */
|
|
font-weight: bold;
|
|
}
|
|
.org-ansi-color-bright-black {
|
|
/* ansi-color-bright-black */
|
|
color: #4d4d4d;
|
|
background-color: #4d4d4d;
|
|
}
|
|
.org-ansi-color-bright-blue {
|
|
/* ansi-color-bright-blue */
|
|
color: #0000ff;
|
|
background-color: #0000ff;
|
|
}
|
|
.org-ansi-color-bright-cyan {
|
|
/* ansi-color-bright-cyan */
|
|
color: #00eeee;
|
|
background-color: #00eeee;
|
|
}
|
|
.org-ansi-color-bright-green {
|
|
/* ansi-color-bright-green */
|
|
color: #00ee00;
|
|
background-color: #00ee00;
|
|
}
|
|
.org-ansi-color-bright-magenta {
|
|
/* ansi-color-bright-magenta */
|
|
color: #ee00ee;
|
|
background-color: #ee00ee;
|
|
}
|
|
.org-ansi-color-bright-red {
|
|
/* ansi-color-bright-red */
|
|
color: #ee0000;
|
|
background-color: #ee0000;
|
|
}
|
|
.org-ansi-color-bright-white {
|
|
/* ansi-color-bright-white */
|
|
color: #ffffff;
|
|
background-color: #ffffff;
|
|
}
|
|
.org-ansi-color-bright-yellow {
|
|
/* ansi-color-bright-yellow */
|
|
color: #eeee00;
|
|
background-color: #eeee00;
|
|
}
|
|
.org-ansi-color-cyan {
|
|
/* ansi-color-cyan */
|
|
color: #00cdcd;
|
|
background-color: #00cdcd;
|
|
}
|
|
.org-ansi-color-faint {
|
|
}
|
|
.org-ansi-color-fast-blink {
|
|
}
|
|
.org-ansi-color-green {
|
|
/* ansi-color-green */
|
|
color: #00cd00;
|
|
background-color: #00cd00;
|
|
}
|
|
.org-ansi-color-inverse {
|
|
}
|
|
.org-ansi-color-italic {
|
|
/* ansi-color-italic */
|
|
font-style: italic;
|
|
}
|
|
.org-ansi-color-magenta {
|
|
/* ansi-color-magenta */
|
|
color: #cd00cd;
|
|
background-color: #cd00cd;
|
|
}
|
|
.org-ansi-color-red {
|
|
/* ansi-color-red */
|
|
color: #cd0000;
|
|
background-color: #cd0000;
|
|
}
|
|
.org-ansi-color-slow-blink {
|
|
}
|
|
.org-ansi-color-underline {
|
|
/* ansi-color-underline */
|
|
text-decoration: underline;
|
|
}
|
|
.org-ansi-color-white {
|
|
/* ansi-color-white */
|
|
color: #e5e5e5;
|
|
background-color: #e5e5e5;
|
|
}
|
|
.org-ansi-color-yellow {
|
|
/* ansi-color-yellow */
|
|
color: #cdcd00;
|
|
background-color: #cdcd00;
|
|
}
|
|
.org-bold {
|
|
/* bold */
|
|
font-weight: bold;
|
|
}
|
|
.org-bold-italic {
|
|
/* bold-italic */
|
|
font-weight: bold;
|
|
font-style: italic;
|
|
}
|
|
.org-border {
|
|
}
|
|
.org-buffer-menu-buffer {
|
|
/* buffer-menu-buffer */
|
|
font-weight: bold;
|
|
}
|
|
.org-builtin {
|
|
/* font-lock-builtin-face */
|
|
color: #483d8b;
|
|
}
|
|
.org-button {
|
|
/* button */
|
|
color: #3a5fcd;
|
|
text-decoration: underline;
|
|
}
|
|
.org-calendar-month-header {
|
|
/* calendar-month-header */
|
|
color: #0000ff;
|
|
}
|
|
.org-calendar-today {
|
|
/* calendar-today */
|
|
text-decoration: underline;
|
|
}
|
|
.org-calendar-weekday-header {
|
|
/* calendar-weekday-header */
|
|
color: #008b8b;
|
|
}
|
|
.org-calendar-weekend-header {
|
|
/* calendar-weekend-header */
|
|
color: #b22222;
|
|
}
|
|
.org-child-frame-border {
|
|
}
|
|
.org-comint-highlight-input {
|
|
/* comint-highlight-input */
|
|
font-weight: bold;
|
|
}
|
|
.org-comint-highlight-prompt {
|
|
/* comint-highlight-prompt */
|
|
color: #0000cd;
|
|
}
|
|
.org-comment {
|
|
/* font-lock-comment-face */
|
|
color: #b22222;
|
|
}
|
|
.org-comment-delimiter {
|
|
/* font-lock-comment-delimiter-face */
|
|
color: #b22222;
|
|
}
|
|
.org-completions-common-part {
|
|
/* completions-common-part */
|
|
color: #0000cd;
|
|
}
|
|
.org-completions-first-difference {
|
|
/* completions-first-difference */
|
|
font-weight: bold;
|
|
}
|
|
.org-completions-group-separator {
|
|
/* completions-group-separator */
|
|
color: #7f7f7f;
|
|
text-decoration: line-through;
|
|
}
|
|
.org-completions-group-title {
|
|
/* completions-group-title */
|
|
color: #7f7f7f;
|
|
font-style: italic;
|
|
}
|
|
.org-completions-highlight {
|
|
/* completions-highlight */
|
|
background-color: #b4eeb4;
|
|
}
|
|
.org-confusingly-reordered {
|
|
/* confusingly-reordered */
|
|
text-decoration: underline;
|
|
}
|
|
.org-constant {
|
|
/* font-lock-constant-face */
|
|
color: #008b8b;
|
|
}
|
|
.org-cursor {
|
|
/* cursor */
|
|
background-color: #000000;
|
|
}
|
|
.org-default {
|
|
/* default */
|
|
color: #000000;
|
|
background-color: #ffffff;
|
|
}
|
|
.org-diary {
|
|
/* diary */
|
|
color: #ff0000;
|
|
}
|
|
.org-doc {
|
|
/* font-lock-doc-face */
|
|
color: #8b2252;
|
|
}
|
|
.org-doc-markup {
|
|
/* font-lock-doc-markup-face */
|
|
color: #008b8b;
|
|
}
|
|
.org-eldoc-highlight-function-argument {
|
|
/* eldoc-highlight-function-argument */
|
|
font-weight: bold;
|
|
}
|
|
.org-elisp-shorthand-font-lock {
|
|
/* elisp-shorthand-font-lock-face */
|
|
color: #00ffff;
|
|
}
|
|
.org-error {
|
|
/* error */
|
|
color: #ff0000;
|
|
font-weight: bold;
|
|
}
|
|
.org-escape-glyph {
|
|
/* escape-glyph */
|
|
color: #a52a2a;
|
|
}
|
|
.org-file-name-shadow {
|
|
/* file-name-shadow */
|
|
color: #7f7f7f;
|
|
}
|
|
.org-fill-column-indicator {
|
|
/* fill-column-indicator */
|
|
color: #7f7f7f;
|
|
}
|
|
.org-fixed-pitch {
|
|
}
|
|
.org-fixed-pitch-serif {
|
|
}
|
|
.org-fringe {
|
|
/* fringe */
|
|
background-color: #f2f2f2;
|
|
}
|
|
.org-function-name {
|
|
/* font-lock-function-name-face */
|
|
color: #0000ff;
|
|
}
|
|
.org-glyphless-char {
|
|
/* glyphless-char */
|
|
font-size: 60%;
|
|
}
|
|
.org-header-line {
|
|
/* header-line */
|
|
color: #333333;
|
|
background-color: #e5e5e5;
|
|
}
|
|
.org-header-line-highlight {
|
|
}
|
|
.org-help-argument-name {
|
|
/* help-argument-name */
|
|
font-style: italic;
|
|
}
|
|
.org-help-for-help-header {
|
|
/* help-for-help-header */
|
|
font-size: 126%;
|
|
}
|
|
.org-help-key-binding {
|
|
/* help-key-binding */
|
|
color: #00008b;
|
|
background-color: #f5f5f5;
|
|
}
|
|
.org-highlight {
|
|
/* highlight */
|
|
background-color: #b4eeb4;
|
|
}
|
|
.org-holiday {
|
|
/* holiday */
|
|
background-color: #ffc0cb;
|
|
}
|
|
.org-homoglyph {
|
|
/* homoglyph */
|
|
color: #a52a2a;
|
|
}
|
|
.org-icon {
|
|
}
|
|
.org-icon-button {
|
|
/* icon-button */
|
|
color: #000000;
|
|
background-color: #808080;
|
|
}
|
|
.org-internal-border {
|
|
}
|
|
.org-isearch {
|
|
/* isearch */
|
|
color: #b0e2ff;
|
|
background-color: #cd00cd;
|
|
}
|
|
.org-isearch-fail {
|
|
/* isearch-fail */
|
|
background-color: #ffc1c1;
|
|
}
|
|
.org-isearch-group-1 {
|
|
/* isearch-group-1 */
|
|
color: #b0e2ff;
|
|
background-color: #f000f0;
|
|
}
|
|
.org-isearch-group-2 {
|
|
/* isearch-group-2 */
|
|
color: #b0e2ff;
|
|
background-color: #a000a0;
|
|
}
|
|
.org-italic {
|
|
/* italic */
|
|
font-style: italic;
|
|
}
|
|
.org-keyword {
|
|
/* font-lock-keyword-face */
|
|
color: #a020f0;
|
|
}
|
|
.org-lazy-highlight {
|
|
/* lazy-highlight */
|
|
background-color: #afeeee;
|
|
}
|
|
.org-line-number-current-line {
|
|
/* line-number-current-line */
|
|
color: #7f7f7f;
|
|
background-color: #ffffff;
|
|
}
|
|
.org-line-number-major-tick {
|
|
/* line-number-major-tick */
|
|
background-color: #d9d9d9;
|
|
font-weight: bold;
|
|
}
|
|
.org-line-number-minor-tick {
|
|
/* line-number-minor-tick */
|
|
background-color: #f2f2f2;
|
|
font-weight: bold;
|
|
}
|
|
.org-link {
|
|
/* link */
|
|
color: #3a5fcd;
|
|
text-decoration: underline;
|
|
}
|
|
.org-link-visited {
|
|
/* link-visited */
|
|
color: #8b008b;
|
|
text-decoration: underline;
|
|
}
|
|
.org-match {
|
|
/* match */
|
|
background-color: #fff68f;
|
|
}
|
|
.org-menu {
|
|
}
|
|
.org-minibuffer-prompt {
|
|
/* minibuffer-prompt */
|
|
color: #0000cd;
|
|
}
|
|
.org-mode-line {
|
|
/* mode-line */
|
|
color: #000000;
|
|
background-color: #bfbfbf;
|
|
}
|
|
.org-mode-line-active {
|
|
/* mode-line-active */
|
|
color: #000000;
|
|
background-color: #bfbfbf;
|
|
}
|
|
.org-mode-line-buffer-id {
|
|
/* mode-line-buffer-id */
|
|
font-weight: bold;
|
|
}
|
|
.org-mode-line-emphasis {
|
|
/* mode-line-emphasis */
|
|
font-weight: bold;
|
|
}
|
|
.org-mode-line-highlight {
|
|
}
|
|
.org-mode-line-inactive {
|
|
/* mode-line-inactive */
|
|
color: #333333;
|
|
background-color: #e5e5e5;
|
|
}
|
|
.org-mouse {
|
|
}
|
|
.org-mouse-drag-and-drop-region {
|
|
/* mouse-drag-and-drop-region */
|
|
background-color: #eedc82;
|
|
}
|
|
.org-negation-char {
|
|
}
|
|
.org-next-error {
|
|
/* next-error */
|
|
background-color: #eedc82;
|
|
}
|
|
.org-next-error-message {
|
|
/* next-error-message */
|
|
background-color: #b4eeb4;
|
|
}
|
|
.org-nobreak-hyphen {
|
|
/* nobreak-hyphen */
|
|
color: #a52a2a;
|
|
}
|
|
.org-nobreak-space {
|
|
/* nobreak-space */
|
|
color: #a52a2a;
|
|
text-decoration: underline;
|
|
}
|
|
.org-org-agenda-calendar-event {
|
|
/* org-agenda-calendar-event */
|
|
color: #000000;
|
|
background-color: #ffffff;
|
|
}
|
|
.org-org-agenda-calendar-sexp {
|
|
/* org-agenda-calendar-sexp */
|
|
color: #000000;
|
|
background-color: #ffffff;
|
|
}
|
|
.org-org-agenda-clocking {
|
|
/* org-agenda-clocking */
|
|
background-color: #ffff00;
|
|
}
|
|
.org-org-agenda-column-dateline {
|
|
/* org-agenda-column-dateline */
|
|
background-color: #e5e5e5;
|
|
}
|
|
.org-org-agenda-current-time {
|
|
/* org-agenda-current-time */
|
|
color: #b8860b;
|
|
}
|
|
.org-org-agenda-date {
|
|
/* org-agenda-date */
|
|
color: #0000ff;
|
|
}
|
|
.org-org-agenda-date-today {
|
|
/* org-agenda-date-today */
|
|
color: #0000ff;
|
|
font-weight: bold;
|
|
font-style: italic;
|
|
}
|
|
.org-org-agenda-date-weekend {
|
|
/* org-agenda-date-weekend */
|
|
color: #0000ff;
|
|
font-weight: bold;
|
|
}
|
|
.org-org-agenda-date-weekend-today {
|
|
/* org-agenda-date-weekend-today */
|
|
color: #0000ff;
|
|
font-weight: bold;
|
|
font-style: italic;
|
|
}
|
|
.org-org-agenda-diary {
|
|
/* org-agenda-diary */
|
|
color: #000000;
|
|
background-color: #ffffff;
|
|
}
|
|
.org-org-agenda-dimmed-todo {
|
|
/* org-agenda-dimmed-todo-face */
|
|
color: #7f7f7f;
|
|
}
|
|
.org-org-agenda-done {
|
|
/* org-agenda-done */
|
|
color: #228b22;
|
|
}
|
|
.org-org-agenda-filter-category {
|
|
/* org-agenda-filter-category */
|
|
color: #000000;
|
|
background-color: #bfbfbf;
|
|
}
|
|
.org-org-agenda-filter-effort {
|
|
/* org-agenda-filter-effort */
|
|
color: #000000;
|
|
background-color: #bfbfbf;
|
|
}
|
|
.org-org-agenda-filter-regexp {
|
|
/* org-agenda-filter-regexp */
|
|
color: #000000;
|
|
background-color: #bfbfbf;
|
|
}
|
|
.org-org-agenda-filter-tags {
|
|
/* org-agenda-filter-tags */
|
|
color: #000000;
|
|
background-color: #bfbfbf;
|
|
}
|
|
.org-org-agenda-restriction-lock {
|
|
/* org-agenda-restriction-lock */
|
|
background-color: #eeeeee;
|
|
}
|
|
.org-org-agenda-structure {
|
|
/* org-agenda-structure */
|
|
color: #0000ff;
|
|
}
|
|
.org-org-agenda-structure-secondary {
|
|
/* org-agenda-structure-secondary */
|
|
color: #0000ff;
|
|
}
|
|
.org-org-archived {
|
|
/* org-archived */
|
|
color: #7f7f7f;
|
|
}
|
|
.org-org-block {
|
|
/* org-block */
|
|
color: #7f7f7f;
|
|
}
|
|
.org-org-block-begin-line {
|
|
/* org-block-begin-line */
|
|
color: #b22222;
|
|
}
|
|
.org-org-block-end-line {
|
|
/* org-block-end-line */
|
|
color: #b22222;
|
|
}
|
|
.org-org-checkbox {
|
|
/* org-checkbox */
|
|
font-weight: bold;
|
|
}
|
|
.org-org-checkbox-statistics-done {
|
|
/* org-checkbox-statistics-done */
|
|
color: #228b22;
|
|
font-weight: bold;
|
|
}
|
|
.org-org-checkbox-statistics-todo {
|
|
/* org-checkbox-statistics-todo */
|
|
color: #ff0000;
|
|
font-weight: bold;
|
|
}
|
|
.org-org-cite {
|
|
/* org-cite */
|
|
color: #3a5fcd;
|
|
text-decoration: underline;
|
|
}
|
|
.org-org-cite-key {
|
|
/* org-cite-key */
|
|
color: #3a5fcd;
|
|
text-decoration: underline;
|
|
}
|
|
.org-org-clock-overlay {
|
|
/* org-clock-overlay */
|
|
color: #000000;
|
|
background-color: #d3d3d3;
|
|
}
|
|
.org-org-code {
|
|
/* org-code */
|
|
color: #7f7f7f;
|
|
}
|
|
.org-org-column {
|
|
/* org-column */
|
|
background-color: #e5e5e5;
|
|
}
|
|
.org-org-column-title {
|
|
/* org-column-title */
|
|
background-color: #e5e5e5;
|
|
font-weight: bold;
|
|
text-decoration: underline;
|
|
}
|
|
.org-org-date {
|
|
/* org-date */
|
|
color: #a020f0;
|
|
text-decoration: underline;
|
|
}
|
|
.org-org-date-selected {
|
|
/* org-date-selected */
|
|
color: #ff0000;
|
|
}
|
|
.org-org-default {
|
|
/* org-default */
|
|
color: #000000;
|
|
background-color: #ffffff;
|
|
}
|
|
.org-org-dispatcher-highlight {
|
|
/* org-dispatcher-highlight */
|
|
color: #00008b;
|
|
background-color: #c6e2ff;
|
|
font-weight: bold;
|
|
}
|
|
.org-org-document-info {
|
|
/* org-document-info */
|
|
color: #191970;
|
|
}
|
|
.org-org-document-info-keyword {
|
|
/* org-document-info-keyword */
|
|
color: #7f7f7f;
|
|
}
|
|
.org-org-document-title {
|
|
/* org-document-title */
|
|
color: #191970;
|
|
font-weight: bold;
|
|
}
|
|
.org-org-done {
|
|
/* org-done */
|
|
color: #228b22;
|
|
font-weight: bold;
|
|
}
|
|
.org-org-drawer {
|
|
/* org-drawer */
|
|
color: #0000ff;
|
|
}
|
|
.org-org-ellipsis {
|
|
/* org-ellipsis */
|
|
color: #b8860b;
|
|
text-decoration: underline;
|
|
}
|
|
.org-org-footnote {
|
|
/* org-footnote */
|
|
color: #a020f0;
|
|
text-decoration: underline;
|
|
}
|
|
.org-org-formula {
|
|
/* org-formula */
|
|
color: #b22222;
|
|
}
|
|
.org-org-headline-done {
|
|
/* org-headline-done */
|
|
color: #bc8f8f;
|
|
}
|
|
.org-org-headline-todo {
|
|
/* org-headline-todo */
|
|
color: #8b0000;
|
|
}
|
|
.org-org-hide {
|
|
/* org-hide */
|
|
color: #ffffff;
|
|
}
|
|
.org-org-imminent-deadline {
|
|
/* org-imminent-deadline */
|
|
color: #ff0000;
|
|
font-weight: bold;
|
|
}
|
|
.org-org-latex-and-related {
|
|
/* org-latex-and-related */
|
|
color: #8b4513;
|
|
}
|
|
.org-org-level-1 {
|
|
/* org-level-1 */
|
|
color: #0000ff;
|
|
}
|
|
.org-org-level-2 {
|
|
/* org-level-2 */
|
|
color: #a0522d;
|
|
}
|
|
.org-org-level-3 {
|
|
/* org-level-3 */
|
|
color: #a020f0;
|
|
}
|
|
.org-org-level-4 {
|
|
/* org-level-4 */
|
|
color: #b22222;
|
|
}
|
|
.org-org-level-5 {
|
|
/* org-level-5 */
|
|
color: #228b22;
|
|
}
|
|
.org-org-level-6 {
|
|
/* org-level-6 */
|
|
color: #008b8b;
|
|
}
|
|
.org-org-level-7 {
|
|
/* org-level-7 */
|
|
color: #483d8b;
|
|
}
|
|
.org-org-level-8 {
|
|
/* org-level-8 */
|
|
color: #8b2252;
|
|
}
|
|
.org-org-link {
|
|
/* org-link */
|
|
color: #3a5fcd;
|
|
text-decoration: underline;
|
|
}
|
|
.org-org-list-dt {
|
|
/* org-list-dt */
|
|
font-weight: bold;
|
|
}
|
|
.org-org-macro {
|
|
/* org-macro */
|
|
color: #8b4513;
|
|
}
|
|
.org-org-meta-line {
|
|
/* org-meta-line */
|
|
color: #b22222;
|
|
}
|
|
.org-org-mode-line-clock {
|
|
/* org-mode-line-clock */
|
|
color: #000000;
|
|
background-color: #bfbfbf;
|
|
}
|
|
.org-org-mode-line-clock-overrun {
|
|
/* org-mode-line-clock-overrun */
|
|
color: #000000;
|
|
background-color: #ff0000;
|
|
}
|
|
.org-org-priority {
|
|
/* org-priority */
|
|
color: #a020f0;
|
|
}
|
|
.org-org-property-value {
|
|
}
|
|
.org-org-quote {
|
|
/* org-quote */
|
|
color: #7f7f7f;
|
|
}
|
|
.org-org-scheduled {
|
|
/* org-scheduled */
|
|
color: #006400;
|
|
}
|
|
.org-org-scheduled-previously {
|
|
/* org-scheduled-previously */
|
|
color: #b22222;
|
|
}
|
|
.org-org-scheduled-today {
|
|
/* org-scheduled-today */
|
|
color: #006400;
|
|
}
|
|
.org-org-sexp-date {
|
|
/* org-sexp-date */
|
|
color: #a020f0;
|
|
}
|
|
.org-org-special-keyword {
|
|
/* org-special-keyword */
|
|
color: #a020f0;
|
|
}
|
|
.org-org-table {
|
|
/* org-table */
|
|
color: #0000ff;
|
|
}
|
|
.org-org-table-header {
|
|
/* org-table-header */
|
|
color: #000000;
|
|
background-color: #d3d3d3;
|
|
}
|
|
.org-org-tag {
|
|
/* org-tag */
|
|
font-weight: bold;
|
|
}
|
|
.org-org-tag-group {
|
|
/* org-tag-group */
|
|
font-weight: bold;
|
|
}
|
|
.org-org-target {
|
|
/* org-target */
|
|
text-decoration: underline;
|
|
}
|
|
.org-org-time-grid {
|
|
/* org-time-grid */
|
|
color: #b8860b;
|
|
}
|
|
.org-org-todo {
|
|
/* org-todo */
|
|
color: #ff0000;
|
|
font-weight: bold;
|
|
}
|
|
.org-org-upcoming-deadline {
|
|
/* org-upcoming-deadline */
|
|
color: #b22222;
|
|
}
|
|
.org-org-upcoming-distant-deadline {
|
|
/* org-upcoming-distant-deadline */
|
|
color: #000000;
|
|
background-color: #ffffff;
|
|
}
|
|
.org-org-verbatim {
|
|
/* org-verbatim */
|
|
color: #7f7f7f;
|
|
}
|
|
.org-org-verse {
|
|
/* org-verse */
|
|
color: #7f7f7f;
|
|
}
|
|
.org-org-warning {
|
|
/* org-warning */
|
|
color: #ff0000;
|
|
font-weight: bold;
|
|
}
|
|
.org-outline-1 {
|
|
/* outline-1 */
|
|
color: #0000ff;
|
|
}
|
|
.org-outline-2 {
|
|
/* outline-2 */
|
|
color: #a0522d;
|
|
}
|
|
.org-outline-3 {
|
|
/* outline-3 */
|
|
color: #a020f0;
|
|
}
|
|
.org-outline-4 {
|
|
/* outline-4 */
|
|
color: #b22222;
|
|
}
|
|
.org-outline-5 {
|
|
/* outline-5 */
|
|
color: #228b22;
|
|
}
|
|
.org-outline-6 {
|
|
/* outline-6 */
|
|
color: #008b8b;
|
|
}
|
|
.org-outline-7 {
|
|
/* outline-7 */
|
|
color: #483d8b;
|
|
}
|
|
.org-outline-8 {
|
|
/* outline-8 */
|
|
color: #8b2252;
|
|
}
|
|
.org-preprocessor {
|
|
/* font-lock-preprocessor-face */
|
|
color: #483d8b;
|
|
}
|
|
.org-query-replace {
|
|
/* query-replace */
|
|
color: #b0e2ff;
|
|
background-color: #cd00cd;
|
|
}
|
|
.org-regexp-grouping-backslash {
|
|
/* font-lock-regexp-grouping-backslash */
|
|
font-weight: bold;
|
|
}
|
|
.org-regexp-grouping-construct {
|
|
/* font-lock-regexp-grouping-construct */
|
|
font-weight: bold;
|
|
}
|
|
.org-region {
|
|
/* region */
|
|
background-color: #eedc82;
|
|
}
|
|
.org-scroll-bar {
|
|
}
|
|
.org-secondary-selection {
|
|
/* secondary-selection */
|
|
background-color: #ffff00;
|
|
}
|
|
.org-separator-line {
|
|
/* separator-line */
|
|
background-color: #a0a0a0;
|
|
font-size: 10%;
|
|
}
|
|
.org-shadow {
|
|
/* shadow */
|
|
color: #7f7f7f;
|
|
}
|
|
.org-show-paren-match {
|
|
/* show-paren-match */
|
|
background-color: #40e0d0;
|
|
}
|
|
.org-show-paren-match-expression {
|
|
/* show-paren-match-expression */
|
|
background-color: #40e0d0;
|
|
}
|
|
.org-show-paren-mismatch {
|
|
/* show-paren-mismatch */
|
|
color: #ffffff;
|
|
background-color: #a020f0;
|
|
}
|
|
.org-string {
|
|
/* font-lock-string-face */
|
|
color: #8b2252;
|
|
}
|
|
.org-success {
|
|
/* success */
|
|
color: #228b22;
|
|
font-weight: bold;
|
|
}
|
|
.org-tab-bar {
|
|
/* tab-bar */
|
|
color: #000000;
|
|
background-color: #d9d9d9;
|
|
}
|
|
.org-tab-bar-tab {
|
|
/* tab-bar-tab */
|
|
color: #000000;
|
|
background-color: #d9d9d9;
|
|
}
|
|
.org-tab-bar-tab-group-current {
|
|
/* tab-bar-tab-group-current */
|
|
color: #000000;
|
|
background-color: #d9d9d9;
|
|
font-weight: bold;
|
|
}
|
|
.org-tab-bar-tab-inactive {
|
|
/* tab-bar-tab-inactive */
|
|
color: #000000;
|
|
background-color: #bfbfbf;
|
|
}
|
|
.org-tab-line {
|
|
/* tab-line */
|
|
color: #000000;
|
|
background-color: #d9d9d9;
|
|
font-size: 90%;
|
|
}
|
|
.org-table-cell {
|
|
/* table-cell */
|
|
color: #e5e5e5;
|
|
background-color: #0000ff;
|
|
}
|
|
.org-tabulated-list-fake-header {
|
|
/* tabulated-list-fake-header */
|
|
font-weight: bold;
|
|
text-decoration: underline;
|
|
text-decoration: overline;
|
|
}
|
|
.org-tool-bar {
|
|
/* tool-bar */
|
|
color: #000000;
|
|
background-color: #bfbfbf;
|
|
}
|
|
.org-tooltip {
|
|
/* tooltip */
|
|
color: #000000;
|
|
background-color: #ffffe0;
|
|
}
|
|
.org-trailing-whitespace {
|
|
/* trailing-whitespace */
|
|
background-color: #ff0000;
|
|
}
|
|
.org-tty-menu-disabled {
|
|
/* tty-menu-disabled-face */
|
|
color: #d3d3d3;
|
|
background-color: #0000ff;
|
|
}
|
|
.org-tty-menu-enabled {
|
|
/* tty-menu-enabled-face */
|
|
color: #ffff00;
|
|
background-color: #0000ff;
|
|
font-weight: bold;
|
|
}
|
|
.org-tty-menu-selected {
|
|
/* tty-menu-selected-face */
|
|
background-color: #ff0000;
|
|
}
|
|
.org-type {
|
|
/* font-lock-type-face */
|
|
color: #228b22;
|
|
}
|
|
.org-underline {
|
|
/* underline */
|
|
text-decoration: underline;
|
|
}
|
|
.org-variable-name {
|
|
/* font-lock-variable-name-face */
|
|
color: #a0522d;
|
|
}
|
|
.org-variable-pitch {
|
|
}
|
|
.org-variable-pitch-text {
|
|
/* variable-pitch-text */
|
|
font-size: 110%;
|
|
}
|
|
.org-vc-conflict-state {
|
|
}
|
|
.org-vc-edited-state {
|
|
}
|
|
.org-vc-locally-added-state {
|
|
}
|
|
.org-vc-locked-state {
|
|
}
|
|
.org-vc-missing-state {
|
|
}
|
|
.org-vc-needs-update-state {
|
|
}
|
|
.org-vc-removed-state {
|
|
}
|
|
.org-vc-state-base {
|
|
}
|
|
.org-vc-up-to-date-state {
|
|
}
|
|
.org-vertical-border {
|
|
}
|
|
.org-warning {
|
|
/* font-lock-warning-face */
|
|
color: #ff0000;
|
|
font-weight: bold;
|
|
}
|
|
.org-warning-1 {
|
|
/* warning */
|
|
color: #ff8c00;
|
|
font-weight: bold;
|
|
}
|
|
.org-window-divider {
|
|
/* window-divider */
|
|
color: #999999;
|
|
}
|
|
.org-window-divider-first-pixel {
|
|
/* window-divider-first-pixel */
|
|
color: #cccccc;
|
|
}
|
|
.org-window-divider-last-pixel {
|
|
/* window-divider-last-pixel */
|
|
color: #666666;
|
|
}
|
|
-->
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<header id="preamble" class="status">
|
|
<div class='navigation'>
|
|
<a href="/index.html">Home</a>
|
|
- <a href="/about.html">About</a>
|
|
- <a href="/blog.html">Blog</a>
|
|
- <a href="/contact.html">Contact</a>
|
|
</div>
|
|
</header>
|
|
<main id="content" class="content">
|
|
<header>
|
|
<h1 class="title">Emacs Lisp is Probably Faster Than What You Think</h1>
|
|
<p class="subtitle" role="doc-subtitle">December 15, 2022</p>
|
|
</header><p>
|
|
Emacs Lisp is the native language of GNU <a href="https://gnu.org/software/emacs">Emacs</a>, an interpreted
|
|
language. We are used to think that interpreted language are slow.
|
|
Yes, they are indeed slower than compiled languages like C and
|
|
Assembly. But with the latest additions like JIT, native-compilation
|
|
and various optimizations, they are catching up with compiled
|
|
languages.
|
|
</p>
|
|
|
|
<p>
|
|
I got the first surprise when I tested <a href="https://gnu.org/software/guile">GNU Guile</a>. It is really fast,
|
|
as fast as C in many cases, when JIT is enabled. However, Emacs Lisp
|
|
is not so fast, but it's OK for most use cases.
|
|
</p>
|
|
|
|
<p>
|
|
But two weeks ago, I got a surprise with Emacs Lisp. I was
|
|
implementing multi-column character support in <a href="https://codeberg.org/akib/emacs-eat">Eat</a>. I found an
|
|
efficient way implement this while not breaking existing code. But it
|
|
had one problem, as you might have already guessed, I needed to find
|
|
all multi-column and zero column (yes, there are some) characters in
|
|
the output. At first, I used a binary search-like algorithm using
|
|
<code>string-width</code>, as I thought C code is fast. Not only it produced too
|
|
much garbage, it also didn't work for obvious reason. Understanding
|
|
the problem, I decided to use <code>char-width</code>. After the initial
|
|
implementation, I thought it was going to make Eat much slow, since it
|
|
needs to check every character of the output string. But to my utter
|
|
surprise, it didn't slow down Eat more than 3-4%. So I happily
|
|
<a href="https://codeberg.org/akib/emacs-eat/commit/9d14bbeaa5c7f5499dcde485ef3a539f8590088e">committed and published it</a>.
|
|
</p>
|
|
|
|
<p>
|
|
Two days ago, learning from the previous incident, I thought to try
|
|
replacing the regular expressions based output parser with a parses
|
|
output one character at a time. After implementing it, I tested it.
|
|
But it was not measurably faster than the old code, so I decided to
|
|
abandon the ready to commit change, out of the fear of breaking
|
|
programs.
|
|
</p>
|
|
|
|
<p>
|
|
But today, I thought to give it another change. My browser was open
|
|
when I tested back then. The browser usually takes up all my memory,
|
|
slowing down everything on my 4 GB RAM computer. But this time the
|
|
browser was not running. After testing, I found that it is actually
|
|
about 5% faster when Eat is native-compiled, which was more than I
|
|
expected. That means the Emacs Lisp based parser is faster than thea
|
|
simple regular expression based parser, despite regular expressions
|
|
are implemented in C. As a bonus, the change didn't make the code
|
|
more complicated (I think it simplified the code instead). Being
|
|
happy with it, I decided to <a href="https://codeberg.org/akib/emacs-eat/commit/61695d9671368cf216587a28ee2ea9d90ccf4b1a">commit and publish it</a>.
|
|
</p>
|
|
|
|
<p>
|
|
So the conclusion is that Emacs Lisp can be faster than C when the
|
|
code is efficient and optimized enough. So before you blame Emacs for
|
|
your slow Emacs Lisp code, first check what you wrote!
|
|
</p>
|
|
</main>
|
|
<footer id="postamble" class="status">
|
|
<hr/><div>
|
|
Comments can be send to my email address <a href='mailto:<a href="mailto:akib@disroot.org">akib@disroot.org</a>'><a href="mailto:akib@disroot.org">akib@disroot.org</a></a>.
|
|
</div><br/>
|
|
<div class='footer'>
|
|
<div>Last updated on 2022-12-15 Thu 21:42 +06.<br/>
|
|
Copyright © 2022 Akib Azmain Turja.<br/>
|
|
</div><br/>
|
|
<div>
|
|
Unless otherwise stated, contents are licensed under the terms of the
|
|
CC-BY-SA-4.0 and code samples are licensed under the terms of the GNU
|
|
General Public License as published by the Free Software Foundation;
|
|
either version 3, or (at your option) any later version.
|
|
</div><br/>
|
|
<div class='footer-generator'>
|
|
Made with
|
|
<a href="https://gnu.org/software/emacs/">GNU Emacs</a> 29.0.50
|
|
(<a href="https://orgmode.org">Org</a> mode 9.5.5) on
|
|
<a href="https://gnu.org/">GNU</a>.
|
|
</div></div>
|
|
</footer>
|
|
</body>
|
|
</html>
|