This note compares jot to several popular text editors. See also
https://en.wikipedia.org/wiki/Editor_war
and
https://en.wikipedia.org/wiki/Comparison_of_text_editors
The editors included in this comparison were:
In windowsland
For Raspberry pi these editors were tried:
The tasks can in general be describes as "time loading some stonking-great text file, doing something then exiting without writing". One might reasonably ask "so who's interested in knowing how long it takes to do something with a file several orders of magnitude bigger than I shall ever be dealing with?" The answer is: when our editors are performing some complicated series of programmed operations, the raw performance determines how long we have to sit and stare at a static screen. It also, perhaps, places our editors under stress so we can detect any memory-stress related crashyness.
The run-time comparison used the time_trial.jot script, this launches the editors and calculates elapsed times. This script only reports elapsed times but was used in preference to the linux "time" command as it works equally well in windowsland.
Tests were run using reasonably large files for two reasons:
Both vi and emacs are, by default, case sensitive whereas jot and ecce are not. Case sensitive searches are simpler and one would expect them to run searches a bit faster. All jot runs include a command to make searches case sensitive - this version of ecce appears to be lacking such a command.
The values in the text density section were obtained from the RSS reported by the linux time command, while the editor was processing the big file. e.g:
$ /usr/bin/time -f " %E elapsed, %U user, %S system, %P CPU, (%F major + %R minor) faults, %I io, %M rss" jot big_file.txt -in=%a
In all cases the session was abandoned without writing back to the filing system.
The linux-PC tests were run on a Fedora 34 desktop system with (according to lscpu and lsmem):
The Windows tests were run on the same system under wine and genuine windows 10. Under wine, the headless emacs tasks all failed - complaining it was not connected to a genuine terminal.
The Raspberry pi was:
A sample file of about 500Mb was created by jot using these commands:
$ rm big_file.txt $ jot -in="%eq=ls -RF /usr/lib; %r=ls2list; \
%da= 00 aaa This is the start of the big file; za %o= -append big_file.txt; \ ol100000000 z. m-0((%i.= -binary=32 'q; i'qbr0b %o= -append big_file.txt;, ) %q$=file big_file.txt; f/ size = /-oid o> zqm)0 \ %d$= 00 zzz This is the end of the big file; %o= -append big_file.txt; %a;"
A similar file but with very long lines, was created thusly:
$ rm fat_file.txt $ jot -in="%eq=ls -RF /usr/lib; %r=ls2list; \
%da= 00 aaa This is the start of the fat file; za %o= -append fat_file.txt; \ ol100000000 m-0((%i.= -binary=64 'q; (m-0(jm)0m-)0 r-0i'qbr0b %o= -append fat_file.txt;, ) %q$=file fat_file.txt; f/ size = /-oid o> zqm)0 \ %d$= 00 zzz This is the end of the fat file; %o= -append fat_file.txt; %a;"
The total installed size of some of these editors is not immediately obvious - applying du -b to /usr/share/<name>, in the case of jot the size given is that of the unpacked tarball, this includes includes two statically-linked linux executables and the windows executable:
The image sizes refer to the executable-image size for the most recent linux-64 versions. This just looks at the size of the main image, in the case of emacs, after following links, then ls -l.
The linux-PC versions:
The windows-PC versions:
jot 425984 (dynamically linked and stripped v3.1.0) ecce 470016 vim 2839552 (v8.2) emacs 6541312 (V27.2) nano 792064 (build date July 9th. 2021)
The Raspberry-pi (armv7l-linux) versions:
jot 239596 (v3.2.0 linux stripped image) ecce vim 921704 (the vi installation turned out to be a tiny vim) emacs 21169696 nano 202384
Of course image size depends on how the image is linked. The image in the jot tarballs is statically linked to the ncurses libs to avoid incompatibility problems. It's also not had debugging information stripped out to improve diagnostic support.
So, if anyone out there is still at all bothered about image size and activation times, jot would seem to be a pretty good bet. Although the version supplied in the tarball is about halfway down the pack, the stripped, dynamically linked version is comfortably slimmer than even nano (all of the other contestants were stripped and dynamically linked).
The big file is loaded up and the session exits without any other editing activity while the process is being monitored by the linux time command. And the The RSS result is recorded - this shows the peak memory used. For a big file this should give a reasonable indication of the text packing density.
First the big file:
$ /usr/bin/time -f " %E elapsed, %U user, %S system, %P CPU, (%F major + %R minor) faults, %I io, %M rss" jot big_file.txt -in="%s=case 1; f/zzz/? %a" 0:00.69 elapsed, 0.41 user, 0.25 system, 96% CPU, (1 major + 64164 minor) faults, 296 io, 258996 rss
$ /usr/bin/time -f " %E elapsed, %U user, %S system, %P CPU, (%F major + %R minor) faults, %I io, %M rss" vim big_file.txt +:q 0:00.89 elapsed, 0.52 user, 0.15 system, 76% CPU, (5 major + 29654 minor) faults, 55088 io, 124880 rss
$ /usr/bin/time -f " %E elapsed, %U user, %S system, %P CPU, (%F major + %R minor) faults, %I io, %M rss" emacs -execute '(insert-file-contents "big_file.txt")' -kill 0:02.22 elapsed, 1.01 user, 0.25 system, 57% CPU, (142 major + 32713 minor) faults, 69712 io, 188884 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "big_file.txt") end-of-lisp $ /usr/bin/time -f " %E elapsed, %U user, %S system, %P CPU, (%F major + %R minor) faults, %I io, %M rss" emacs --script x.el 0:00.55 elapsed, 0.42 user, 0.12 system, 99% CPU, (0 major + 29421 minor) faults, 0 io, 158436 rss
$ /usr/bin/time -f " %E elapsed, %U user, %S system, %P CPU, (%F major + %R minor) faults, %I io, %M rss" nano big_file.txt 0:03.28 elapsed, 0.97 user, 0.18 system, 35% CPU, (1 major + 64224 minor) faults, 648 io, 259660 rss
$ /usr/bin/time -f " %E elapsed, %U user, %S system, %P CPU, (%F major + %R minor) faults, %I io, %M rss" ecce big_file.txt 0:03.74 elapsed, 0.95 user, 0.13 system, 28% CPU, (0 major + 48911 minor) faults, 80 io, 196768 rss
In summary: rss
But nano's memory usage goes through the roof when handling the fat file - see postscript
The elapsed time is not particularly reliable in the case of emacs and nano, since these do not seem to offer any options to enter editor commands from the command line. For nano and emacs the session was quickly closed using interactive commands.
PC-linux:
$ time_trial jot t.t -in="%a" 0:00.03 elapsed, 0.03 user, 0.00 system, 94% CPU, (0 major + 431 minor) faults, 0 io, 4028 rss
$ time_trial vim t.t -c:q 0:00.02 elapsed, 0.01 user, 0.00 system, 100% CPU, (0 major + 988 minor) faults, 0 io, 9372 rss
$ time_trial emacs -nw t.t -kill 0:00.18 elapsed, 0.15 user, 0.02 system, 98% CPU, (0 major + 4750 minor) faults, 16 io, 54392 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "t.t") end-of-lisp $ time_trial emacs --script x.el 0:00.11 elapsed, 0.09 user, 0.01 system, 98% CPU, (0 major + 3347 minor) faults, 0 io, 53012 rss
$ time_trial nano t.t
0:00.35 elapsed, 0.00 user, 0.00 system, 3% CPU, (0 major + 715 minor) faults, 0 io, 9740 rss
PC-windows:
$ win_jot t.t -in="%a" 0:01.07 elapsed, 0.08 user, 0.10 system, 17% CPU, (0 major + 3854 minor) faults, 0 io, 21812 rss
$ win_vim t.t -c:q 0:02.55 elapsed, 0.09 user, 0.08 system, 7% CPU, (0 major + 3866 minor) faults, 0 io, 21728 rss
$ win_emacs -nw t.t -kill 0:04.71 elapsed, 0.09 user, 0.10 system, 4% CPU, (0 major + 3850 minor) faults, 0 io, 21868 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "t.t") end-of-lisp $ win_emacs --script x.el 0:02.92 elapsed, 0.10 user, 0.10 system, 7% CPU, (0 major + 3844 minor) faults, 0 io, 21860 rss
$ win_nano t.t
Pi-linux:
$ time jot t.t -in="%a" 0m0.397s
$ time vi t.t -c:q 0m0.028s
$ time emacs -nw t.t -kill 0m1.041s
$ cat - > x.el << end-of-lisp (insert-file-contents "t.t") end-of-lisp $ time emacs --script x.el 0m0.647s
$ time nano t.t
0m0.425s
Apart from the arm version of emacs, these figures are not really important since none of these was less than a few milliseconds. The result for nano should be discounted because it includes the time taken to enter {Ctrl+x} - nano does not seem to have any facility for entering commands from the CLI line.
A sample file of about 500Mb was created by jot using these commands:
$ rm big_file.txt $ jot -in="%eq=ls -RF /usr/lib; %r=ls2list; \
%da= 00 aaa This is the start of the big file; za %o= -append big_file.txt; \ ol500000000 z. m-0((%i.= -binary=32 'q; i'qbr0b %o= -append big_file.txt;, ) %q$=file big_file.txt; f/ size = /-oid o> zqm)0 \ %d$= 00 zzz This is the end of the big file; %o= -append big_file.txt; %a;"
The resultant file was, unfortunately too big for the emacs buffer so it was reduced to 445495954B bu editing.
PC-linux:
$ time_trial jot big_file.txt -in=%a 0:01.55 elapsed, 0.77 user, 0.77 system, 99% CPU, (0 major + 197728 minor) faults, 0 io, 793196 rss
$ time_trial vim big_file.txt -c:q 0:02.10 elapsed, 1.69 user, 0.39 system, 99% CPU, (0 major + 123807 minor) faults, 0 io, 501372 rss
$ time_trial emacs -execute '(insert-file-contents "big_file.txt")' -kill 0:02.30 elapsed, 1.68 user, 0.50 system, 95% CPU, (20 major + 117153 minor) faults, 0 io, 526636 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "big_file.txt") end-of-lisp $ time_trial emacs --script x.el 0:01.76 elapsed, 1.33 user, 0.42 system, 99% CPU, (0 major + 113727 minor) faults, 0 io, 495376 rss
$ time_trial nano big_file.txt
{Ctrl+x} - to exit.
0:04.23 elapsed, 3.11 user, 0.55 system, 86% CPU, (4 major + 197674 minor) faults, 896 io, 793484 rss
PC-windows:
$ win_jot big_file.txt -in=%a 0:04.17 elapsed, 0.10 user, 0.10 system, 4% CPU, (0 major + 3845 minor) faults, 0 io, 21676 rss
$ win_vim big_file.txt -c:q 0:08.60 elapsed, 0.08 user, 0.08 system, 1% CPU, (0 major + 3670 minor) faults, 0 io, 21944 rss
$ win_emacs -execute '(insert-file-contents "big_file.txt")' -kill 0:06.83 elapsed, 0.07 user, 0.07 system, 2% CPU, (0 major + 3674 minor) faults, 0 io, 21836 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "big_file.txt") end-of-lisp $ win_emacs --script x.el 0:04.87 elapsed, 0.06 user, 0.07 system, 2% CPU, (0 major + 3708 minor) faults, 0 io, 21748 rss
$ time_trial nano big_file.txt
{Ctrl+x} - to exit.
Pi-linux:
$ time jot big_file.txt -in=%a 0m24.866s
$ time vi big_file.txt -c:q 0m30.432s
$ time emacs -execute '(insert-file-contents "big_file.txt")' -kill 0m43.753s
$ cat - > x.el << end-of-lisp (insert-file-contents "big_file.txt") end-of-lisp $ time emacs --script x.el 0m32.395s
$ time nano big_file.txt
{Ctrl+x} - to exit.
0m45.516s
The results are all pretty much the same - jot and vim were a bit faster but all were within acceptable limits.
The big_file.txt is loaded again and this time each editor is set to search the entire file for a string that only occurs at the end of the file.
PC-linux:
$ time_trial jot big_file.txt -in="%s=case 1; f/zzz/? %a" 0:01.89 elapsed, 1.09 user, 0.79 system, 99% CPU, (0 major + 197730 minor) faults, 0 io, 793244 rss
$ time_trial vim big_file.txt -c/zzz/ +:q 0:04.99 elapsed, 4.55 user, 0.41 system, 99% CPU, (0 major + 123802 minor) faults, 0 io, 501156 rss
$ time_trial emacs -execute '(insert-file-contents "big_file.txt")' -execute '(search-forward "zzz")' -kill 0:02.84 elapsed, 2.24 user, 0.50 system, 96% CPU, (20 major + 117159 minor) faults, 0 io, 526676 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "big_file.txt") (search-forward "zzz") end-of-lisp $ time_trial emacs --script x.el 0:02.27 elapsed, 1.80 user, 0.45 system, 99% CPU, (0 major + 113725 minor) faults, 0 io, 495236 rss
$ time_trial nano big_file.txt
0:12.15 elapsed, 7.50 user, 0.61 system, 66% CPU, (0 major + 197681 minor) faults, 0 io, 793588 rss
PC-Windows:
$ win_jot big_file.txt -in="f/zzz/ %a" 0:07.24 elapsed, 0.08 user, 0.09 system, 2% CPU, (0 major + 3703 minor) faults, 0 io, 21844 rss
$ win_vim big_file.txt -c/zzz/ -c:q 0:09.53 elapsed, 0.07 user, 0.06 system, 1% CPU, (0 major + 3700 minor) faults, 0 io, 21764 rss
$ win_emacs -execute '(insert-file-contents "big_file.txt")' -kill 0:06.75 elapsed, 0.08 user, 0.09 system, 2% CPU, (0 major + 3701 minor) faults, 0 io, 21684 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "big_file.txt") end-of-lisp $ win_emacs --script x.el 0:04.78 elapsed, 0.09 user, 0.08 system, 3% CPU, (0 major + 3700 minor) faults, 0 io, 21752 rss
$ win_nano big_file.txt
{Ctrl+x} - to exit.
Pi-linux:
$ time jot big_file.txt -in=%a 0m40.613s
$ time vi big_file.txt -c:q 0m28.833s
$ time emacs -execute '(insert-file-contents "big_file.txt")' -kill 0m47.118s
$ cat - > x.el << end-of-lisp (insert-file-contents "big_file.txt") end-of-lisp $ time emacs --script x.el 0m29.190s
$ time nano big_file.txt
{Ctrl+x} - to exit.
0m45.516s
Pi-linux:
$ time jot big_file.txt -in="%s=case 1; f/zzz/? %a" 0m41.093s
$ time vi big_file.txt -c/zzz/ +:q 1m38.429s
$ time emacs -execute '(insert-file-contents "big_file.txt")' -execute '(search-forward "zzz")' -kill 0m28.249s
$ cat - > x.el << end-of-lisp (insert-file-contents "big_file.txt") (search-forward "zzz") end-of-lisp $ time emacs --script x.el 0m40.369s
$ time nano big_file.txt
11m26.101s
Jot shows a small advantage over the other contestants, nano shows a significant disadvantage.
The only reason for doing this is to obtain a slightly more accurate estimate of the reverse-search time (in the following section).
PC-Linux:
$ time_trial jot big_file.txt -in="m0 %a" 0:01.68 elapsed, 0.92 user, 0.75 system, 99% CPU, (0 major + 197728 minor) faults, 0 io, 793200 rss
$ time_trial vim big_file.txt -c:$ +:q! 0:02.18 elapsed, 1.79 user, 0.38 system, 99% CPU, (0 major + 123805 minor) faults, 0 io, 501208 rss
$ time_trial emacs -execute '(insert-file-contents "big_file.txt")' -execute '(goto-char (point-max))' -kill 0:02.37 elapsed, 1.77 user, 0.49 system, 95% CPU, (20 major + 117142 minor) faults, 0 io, 526296 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "big_file.txt") (goto-char (point-max)) end-of-lisp $ time_trial emacs --script x.el 0:30.57 elapsed, 3.27 user, 0.65 system, 12% CPU, (0 major + 197674 minor) faults, 0 io, 793492 rss
$ time_trial nano big_file.txt
{Ctrl+_}{Ctrl+v}{Ctrl+x}
0:09.67 elapsed, 3.24 user, 0.63 system, 40% CPU, (0 major + 197676 minor) faults, 0 io, 793488 rss
PC-Windows:
$ win_jot big_file.txt -in="m0 %a" 0:04.12 elapsed, 0.08 user, 0.08 system, 4% CPU, (0 major + 3672 minor) faults, 0 io, 21600 rss
$ win_vim big_file.txt -c:$ -:q! 0:01.75 elapsed, 0.09 user, 0.10 system, 11% CPU, (0 major + 3853 minor) faults, 0 io, 21852 rss
$ win_emacs -execute '(insert-file-contents "big_file.txt")' -execute '(goto-char (point-max))' -kill 0:06.51 elapsed, 0.08 user, 0.07 system, 2% CPU, (0 major + 3707 minor) faults, 0 io, 21832 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "big_file.txt") (goto-char (point-max)) end-of-lisp $ win_emacs --script x.el 0:04.62 elapsed, 0.08 user, 0.06 system, 3% CPU, (0 major + 3702 minor) faults, 0 io, 21764 rss
$ win_nano big_file.txt
{Ctrl+_}{Ctrl+v}{Ctrl+x}
Pi-Linux:
$ time jot big_file.txt -in="m0 %a" 0:02.29 elapsed, 1.26 user, 1.02 system, 99% CPU, (0 major + 271687 minor) faults, 0 io, 1089072 rss
$ time vim big_file.txt -c:$ +:q! 0:02.98 elapsed, 2.42 user, 0.54 system, 99% CPU, (0 major + 169817 minor) faults, 0 io, 685344 rss
$ time emacs -execute '(insert-file-contents "big_file.txt")' -execute '(goto-char (point-max))' -kill 0:03.02 elapsed, 2.20 user, 0.65 system, 94% CPU, (20 major + 157895 minor) faults, 0 io, 689668 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "big_file.txt") (goto-char (point-max)) end-of-lisp $ time emacs --script x.el 0:02.44 elapsed, 1.81 user, 0.61 system, 99% CPU, (0 major + 154473 minor) faults, 0 io, 658336 rss
$ time nano big_file.txt
{Ctrl+_}{Ctrl+v}{Ctrl+x}
1m0.387s
In this test we ask our editors to go right to the end of a big file and then find a string that appears only at the very beginning of the file.
PC-Linux:
$ time_trial jot big_file.txt -in="%s=case 1; m0 f-/aaa/? %a" 0:03.30 elapsed, 2.50 user, 0.78 system, 99% CPU, (0 major + 197728 minor) faults, 0 io, 793200 rss
$ time_trial vim big_file.txt -c:$ +?aaa? +:q! 0:04.67 elapsed, 4.26 user, 0.39 system, 99% CPU, (0 major + 123807 minor) faults, 0 io, 501300 rss
$ time_trial emacs -execute '(insert-file-contents "big_file.txt")' -execute '(goto-char (point-max))' -execute '(search-backward "aaa")' -kill 0:02.80 elapsed, 2.17 user, 0.50 system, 95% CPU, (20 major + 117139 minor) faults, 0 io, 526244 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "big_file.txt") (goto-char (point-max)) (search-backward "aaa") end-of-lisp $ time_trial emacs --script x.el 0:02.27 elapsed, 1.81 user, 0.44 system, 99% CPU, (0 major + 113725 minor) faults, 0 io, 495296 rss
$ time_trial nano big_file.txt
0:22.25 elapsed, 7.74 user, 0.61 system, 37% CPU, (0 major + 197678 minor) faults, 0 io, 793584 rss
PC-Windows:
$ win_jot big_file.txt -in="%s=case 1; m0 f-/aaa/? %a" 0:05.85 elapsed, 0.10 user, 0.09 system, 3% CPU, (0 major + 3697 minor) faults, 0 io, 21728 rss
$ win_vim big_file.txt -c:$ +?aaa? +:q! 0:09.59 elapsed, 0.08 user, 0.08 system, 1% CPU, (0 major + 4512 minor) faults, 0 io, 21044 rss
$ win_emacs -execute '(insert-file-contents "big_file.txt")' -execute '(goto-char (point-max))' -execute '(search-backward "aaa")' -kill 0:07.39 elapsed, 0.10 user, 0.10 system, 2% CPU, (0 major + 3862 minor) faults, 0 io, 21924 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "big_file.txt") (goto-char (point-max)) (search-backward "aaa") end-of-lisp $ win_emacs --script x.el 0:04.36 elapsed, 0.10 user, 0.10 system, 4% CPU, (0 major + 3866 minor) faults, 0 io, 21692 rss
$ win_nano big_file.txt
<
P>
Pi-Linux:<
/P>
$ time jot big_file.txt -in="%s=case 1; m0 f-/aaa/? %a" 0m48.175s
$ time vi big_file.txt -c:$ +?aaa? +:q! 0m57.635s
$ time emacs -execute '(insert-file-contents "big_file.txt")' \
-execute '(goto-char (point-max))' -execute '(search-backward "aaa")' -kill
0m49.166s
$ cat - > x.el << end-of-lisp (insert-file-contents "big_file.txt") (goto-char (point-max)) (search-backward "aaa") end-of-lisp $ time emacs --script x.el 0m38.495s
$ time nano big_file.txt
1m25.248s
In this case the replacement string is the same length as the original. Originally this was tried with the search string "00", and both jot and vim acquitted themselves quite well but emacs failed miserably and had to be killed after 30 minutes. This failure appears to be something to do with the undo journal it maintains.
So, for this test we use the much less commonly-occurring search string "99".
$ time_trial jot big_file.txt -in="%s=case 1; (f/99/s/zz/)0 %a" 0:02.11 elapsed, 1.35 user, 0.74 system, 99% CPU, (0 major + 197729 minor) faults, 0 io, 793200 rss
$ time_trial vim big_file.txt -c:%s/99/zz/g +:q! 0:05.49 elapsed, 5.05 user, 0.41 system, 99% CPU, (0 major + 123801 minor) faults, 0 io, 501160 rss
$ time_trial emacs -execute '(insert-file-contents "big_file.txt")' -execute '(replace-string "99" "zz")' -kill 0:05.16 elapsed, 4.48 user, 0.53 system, 97% CPU, (110 major + 124575 minor) faults, 0 io, 555964 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "big_file.txt") (replace-string "99" "zz") end-of-lisp $ time_trial emacs --script x.el 0:03.22 elapsed, 2.75 user, 0.45 system, 99% CPU, (0 major + 115753 minor) faults, 0 io, 504012 rss
$ time_trial nano big_file.txt
0:23.45 elapsed, 11.18 user, 0.94 system, 51% CPU, (0 major + 276342 minor) faults, 0 io, 1108164 rss
PC-Windows:
$ win_jot big_file.txt -in="%s=case 1; (f/99/s/zz/)0 %a" 0:04.39 elapsed, 0.09 user, 0.09 system, 4% CPU, (0 major + 3703 minor) faults, 0 io, 21740 rss
$ win_vim big_file.txt -c:%s/99/zz/g +:q! 0:10.04 elapsed, 0.10 user, 0.07 system, 1% CPU, (0 major + 3705 minor) faults, 0 io, 21716 rss
$ win_emacs -execute '(insert-file-contents "big_file.txt")' -execute '(replace-string "99" "zz")' -kill 0:08.94 elapsed, 0.06 user, 0.09 system, 1% CPU, (0 major + 4512 minor) faults, 0 io, 20896 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "big_file.txt") (replace-string "99" "zz") end-of-lisp $ win_emacs --script x.el 0:06.94 elapsed, 0.08 user, 0.06 system, 2% CPU, (0 major + 3708 minor) faults, 0 io, 21748 rss
$ win_nano big_file.txt
Pi-linux:
$ time jot big_file.txt -in="%s=case 1; (f/99/s/zz/)0 %a" 0m42.438s
$ time vi big_file.txt -c:%s/99/zz/g +:q! 1m46.156s
$ time emacs -execute '(insert-file-contents "big_file.txt")' -execute '(replace-string "99" "zz")' -kill 1m34.565s
$ cat - > x.el << end-of-lisp (insert-file-contents "big_file.txt") (replace-string "99" "zz") end-of-lisp $ time emacs --script x.el 1m0.529s
$ time nano big_file.txt
11m25.974s
In this case the replacement string is the longer than the original. This is an important difference since our editors must somehow shuffle the text and allocate more memory for the extended lines.
$ time_trial jot big_file.txt -in="%s=case 1; (f/99/s/abcdefghi/)0 %a" 0:02.13 elapsed, 1.35 user, 0.77 system, 99% CPU, (0 major + 197861 minor) faults, 0 io, 793768 rss
$ time_trial vi big_file.txt -c:%s/99/abcdefghi/g +:q! 0:06.10 elapsed, 5.66 user, 0.41 system, 99% CPU, (0 major + 127425 minor) faults, 0 io, 515008 rss
$ time_trial emacs -execute '(insert-file-contents "big_file.txt")' -execute '(replace-string "99" "abcdefghi")' -kill 0:05.20 elapsed, 4.56 user, 0.52 system, 97% CPU, (20 major + 126309 minor) faults, 0 io, 562940 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "big_file.txt") (replace-string "99" "abcdefghi") end-of-lisp $ time_trial emacs --script x.el 0:03.36 elapsed, 2.89 user, 0.45 system, 99% CPU, (0 major + 117457 minor) faults, 0 io, 510672 rss
$ time_trial nano big_file.txt
0:28.30 elapsed, 11.34 user, 0.83 system, 43% CPU, (0 major + 276345 minor) faults, 0 io, 1108168 rss
PC-Windows:
$ win_jot big_file.txt -in="%s=case 1; (f/99/s/abcdefghi/)0 %a" 0:04.35 elapsed, 0.06 user, 0.07 system, 3% CPU, (0 major + 3699 minor) faults, 0 io, 21772 rss
$ win_vim big_file.txt -c:%s/99/abcdefghi/g +:q! 0:10.47 elapsed, 0.07 user, 0.07 system, 1% CPU, (0 major + 3695 minor) faults, 0 io, 21824 rss
$ win_emacs -execute '(insert-file-contents "big_file.txt")' -execute '(replace-string "99" "abcdefghi")' -kill 0:25.60 elapsed, 0.07 user, 0.06 system, 0% CPU, (0 major + 3706 minor) faults, 0 io, 21840 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "big_file.txt") (replace-string "99" "abcdefghi") end-of-lisp $ win_emacs --script x.el 0:08.36 elapsed, 0.09 user, 0.09 system, 2% CPU, (0 major + 3839 minor) faults, 0 io, 21784 rss
$ win_nano big_file.txt
Pi-linux:
$ time jot big_file.txt -in="%s=case 1; (f/99/s/abcdefghi/)0 %a" 0m50.851s
$ time vi big_file.txt -c:%s/99/abcdefghi/g +:q! 1m57.930s
$ time emacs -execute '(insert-file-contents "big_file.txt")' -execute '(replace-string "99" "abcdefghi")' -kill 1m27.979s
$ cat - > x.el << end-of-lisp (insert-file-contents "big_file.txt") (replace-string "99" "abcdefghi") end-of-lisp $ time emacs --script x.el 0m58.595s
$ time nano big_file.txt
13m25.384s
In this case the replacement string is the shorter than the original. This is an important difference since our editors must shuffle the text.
PC-Linux:
$ time_trial jot big_file.txt -in="%s=case 1; (f/99/s/a/)0 %a" 0:02.05 elapsed, 1.31 user, 0.73 system, 99% CPU, (0 major + 197726 minor) faults, 0 io, 793236 rss
$ time_trial vim big_file.txt -c:%s/99/a/g +:q! 0:05.95 elapsed, 5.50 user, 0.43 system, 99% CPU, (0 major + 123804 minor) faults, 0 io, 501304 rss
$ time_trial emacs -execute '(insert-file-contents "big_file.txt")' -execute '(replace-string "99" "a")' -kill 0:04.98 elapsed, 4.38 user, 0.52 system, 98% CPU, (100 major + 124603 minor) faults, 0 io, 556044 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "big_file.txt") (replace-string "99" "a") end-of-lisp $ time_trial emacs --script x.el 0:03.20 elapsed, 2.73 user, 0.45 system, 99% CPU, (0 major + 115747 minor) faults, 0 io, 503864 rss
$ time_trial nano big_file.txt
0:16.86 elapsed, 7.81 user, 0.61 system, 49% CPU, (0 major + 201077 minor) faults, 0 io, 807184 rss
PC-Windows:
$ win_jot big_file.txt -in="%s=case 1; (f/99/s/a/)0 %a" 0:04.37 elapsed, 0.07 user, 0.07 system, 3% CPU, (0 major + 3702 minor) faults, 0 io, 21748 rss
$ win_vim big_file.txt -c:%s/99/a/g +:q! 0:10.25 elapsed, 0.09 user, 0.09 system, 1% CPU, (0 major + 3708 minor) faults, 0 io, 21840 rss
$ win_emacs -execute '(insert-file-contents "big_file.txt")' -execute '(replace-string "99" "a")' -kill 0:11.45 elapsed, 0.09 user, 0.08 system, 1% CPU, (0 major + 3708 minor) faults, 0 io, 21664 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "big_file.txt") (replace-string "99" "a") end-of-lisp $ win_emacs --script x.el 0:06.88 elapsed, 0.09 user, 0.07 system, 2% CPU, (0 major + 3712 minor) faults, 0 io, 21676 rss
$ win_nano big_file.txt
PI-linux:
$ time jot big_file.txt -in="%s=case 1; (f/99/s/a/)0 %a" 0m53.286s
$ time vi big_file.txt -c:%s/99/a/g +:q! 1m48.872s
$ time emacs -execute '(insert-file-contents "big_file.txt")' -execute '(replace-string "99" "a")' -kill 1m35.383s
$ cat - > x.el << end-of-lisp (insert-file-contents "big_file.txt") (replace-string "99" "a") end-of-lisp $ time emacs --script x.el 1m2.212s
$ time nano big_file.txt
11m26.070s
PC-Linux:
$ time_trial jot big_file.txt -in="(%f= -rex [^a-zA-Z0-9]99[^a-zA-Z0-9];s/ zz /)0 %a;" 0:20.46 elapsed, 19.63 user, 0.76 system, 99% CPU, (0 major + 197730 minor) faults, 0 io, 793372 rss
$ time_trial vim big_file.txt -c":%s/[^a-zA-Z0-9]99[^a-zA-Z0-9]/ zz /g" +:q! 0:30.25 elapsed, 29.15 user, 0.99 system, 99% CPU, (0 major + 123801 minor) faults, 0 io, 501080 rss
$ time_trial emacs -execute '(insert-file-contents "big_file.txt")' -execute '(replace-regexp "[^a-zA-Z0-9]99[^a-zA-Z0-9]" " zz ")' -kill 0:16.15 elapsed, 15.41 user, 0.53 system, 98% CPU, (40 major + 124537 minor) faults, 0 io, 556192 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "big_file.txt") (replace-regexp "[^a-zA-Z0-9]99[^a-zA-Z0-9]" " zz ") end-of-lisp $ time_trial emacs --script x.el 0:14.26 elapsed, 13.74 user, 0.46 system, 99% CPU, (0 major + 115763 minor) faults, 0 io, 503972 rss
$ time_trial nano big_file.txt
0:45.65 elapsed, 21.38 user, 0.67 system, 48% CPU, (0 major + 200953 minor) faults, 0 io, 806668 rss
PC-Windows:
$ win_jot big_file.txt -in="(%f= -rex [^a-zA-Z0-9]99[^a-zA-Z0-9];s/ zz /)0 %a;" 0:07.51 elapsed, 0.09 user, 0.07 system, 2% CPU, (0 major + 3706 minor) faults, 0 io, 21636 rss
$ win_vim big_file.txt -c":%s/[^a-zA-Z0-9]99[^a-zA-Z0-9]/ zz /g" +:q!
$ win_emacs -execute '(insert-file-contents "big_file.txt")' -execute '(replace-regexp "[^a-zA-Z0-9]99[^a-zA-Z0-9]" " zz ")' -kill 0:28.29 elapsed, 0.07 user, 0.07 system, 0% CPU, (0 major + 3704 minor) faults, 0 io, 21916 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "big_file.txt") (replace-regexp "[^a-zA-Z0-9]99[^a-zA-Z0-9]" " zz ") end-of-lisp $ win_emacs --script x.el 0:23.87 elapsed, 0.10 user, 0.09 system, 0% CPU, (0 major + 3854 minor) faults, 0 io, 21808 rss
$ nano big_file.txt
1:17
Pi-Linux:
$ time jot big_file.txt -in="(%f= -rex [^a-zA-Z0-9]99[^a-zA-Z0-9];s/ zz /)0 %a;" 0:30.06 elapsed, 28.80 user, 1.12 system, 99% CPU, (0 major + 271688 minor) faults, 0 io, 1089224 rss
$ time vim big_file.txt -c":%s/[^a-zA-Z0-9]99[^a-zA-Z0-9]/ zz /g" +:q! 0:44.74 elapsed, 42.89 user, 1.56 system, 99% CPU, (0 major + 169820 minor) faults, 0 io, 685392 rss
$ time emacs -execute '(insert-file-contents "big_file.txt")' -execute '(replace-regexp "[^a-zA-Z0-9]99[^a-zA-Z0-9]" " zz ")' -kill 0:23.27 elapsed, 22.29 user, 0.73 system, 98% CPU, (20 major + 168170 minor) faults, 0 io, 730368 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "big_file.txt") (replace-regexp "[^a-zA-Z0-9]99[^a-zA-Z0-9]" " zz ") end-of-lisp $ time emacs --script x.el 0:20.63 elapsed, 19.85 user, 0.66 system, 99% CPU, (0 major + 157284 minor) faults, 0 io, 669932 rss
$ time nano big_file.txt
PC-Linux:
$ time_trial jot big_file.txt -in="n.m0aaha %a;" 0:04.28 elapsed, 2.63 user, 1.62 system, 99% CPU, (0 major + 542953 minor) faults, 0 io, 2174104 rss
$ rm ~/.viminfo ; time_trial vim big_file.txt
0:24.19 elapsed, 7.30 user, 1.47 system, 36% CPU, (0 major + 545949 minor) faults, 0 io, 2189736 rss
$ time_trial emacs -execute '(insert-file-contents "big_file.txt")' -execute '(kill-region 1 (point-max))' -execute '(yank)' -kill 0:40.71 elapsed, 37.22 user, 2.81 system, 98% CPU, (53 major + 905575 minor) faults, 0 io, 3081920 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "big_file.txt") (kill-region 1 (point-max)) (yank) end-of-lisp $ time_trial emacs --script x.el 0:03.67 elapsed, 2.73 user, 0.91 system, 99% CPU, (0 major + 304025 minor) faults, 0 io, 1256872 rss
$ time_trial nano big_file.txt
0:25.00 elapsed, 8.50 user, 2.75 system, 45% CPU, (0 major + 1085477 minor) faults, 0 io, 4344692 rss
PC-Windows:
$ win_jot big_file.txt -in="n.m0aaha %a;" 0:08.35 elapsed, 0.07 user, 0.07 system, 1% CPU, (0 major + 3680 minor) faults, 0 io, 21648 rss
$ win_vim big_file.txt
0:24.19 elapsed, 7.30 user, 1.47 system, 36% CPU, (0 major + 545949 minor) faults, 0 io, 2189736 rss
$ win_emacs -execute '(insert-file-contents "big_file.txt")' -execute '(kill-region 1 (point-max))' -execute '(yank)' -kill 0:17.99 elapsed, 0.08 user, 0.06 system, 0% CPU, (0 major + 3688 minor) faults, 0 io, 21724 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "big_file.txt") (kill-region 1 (point-max)) (yank) end-of-lisp $ win_emacs --script x.el 0:15.76 elapsed, 0.07 user, 0.08 system, 1% CPU, (0 major + 3693 minor) faults, 0 io, 21916 rss
$ nano big_file.txt
Pi-Linux:
$ time_trial jot big_file.txt -in="n.m0aaha %a;" 0:04.46 elapsed, 2.71 user, 1.72 system, 99% CPU, (0 major + 542957 minor) faults, 0 io, 2174148 rss
$ time_trial vim big_file.txt
0:24.19 elapsed, 7.30 user, 1.47 system, 36% CPU, (0 major + 545949 minor) faults, 0 io, 2189736 rss
$ time_trial emacs -execute '(insert-file-contents "big_file.txt")' -execute '(kill-region 1 (point-max))' -execute '(yank)' -kill 0:40.94 elapsed, 37.30 user, 3.13 system, 98% CPU, (43 major + 905556 minor) faults, 0 io, 3082256 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "big_file.txt") (kill-region 1 (point-max)) (yank) end-of-lisp $ time_trial emacs --script x.el 0:04.02 elapsed, 2.90 user, 1.09 system, 99% CPU, (0 major + 304028 minor) faults, 0 io, 1256880 rss
$ time_trial nano big_file.txt
0:24.87 elapsed, 8.77 user, 2.66 system, 46% CPU, (2 major + 1085480 minor) faults, 296 io, 4344716 rss
A file of just under 300Mb was created with these commands, it has 547 lines of varying length, some over 20Mb, most are several hundred Kb long. There are 18356191 instances of the string "00" and 50192 instances of the string "99".
This series of tests is intended to compare performance for handling files with long lines.
PC-Linux:
$ time_trial jot fat_file.txt -in=%a 0:00.56 elapsed, 0.19 user, 0.36 system, 99% CPU, (0 major + 86778 minor) faults, 0 io, 294860 rss
$ time_trial vim fat_file.txt -c:q 0:02.04 elapsed, 1.73 user, 0.30 system, 99% CPU, (0 major + 92282 minor) faults, 0 io, 318832 rss
$ time_trial emacs -execute '(insert-file-contents "fat_file.txt")' -kill 0:01.74 elapsed, 1.26 user, 0.37 system, 94% CPU, (20 major + 80863 minor) faults, 0 io, 381096 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "fat_file.txt") end-of-lisp $ time_trial emacs --script x.el 0:01.21 elapsed, 0.89 user, 0.31 system, 99% CPU, (0 major + 77449 minor) faults, 0 io, 350080 rss
$ time_trial nano fat_file.txt
0:02.68 elapsed, 2.37 user, 0.27 system, 98% CPU, (4 major + 75143 minor) faults, 928 io, 303200 rss
PC-Windows:
$ win_jot fat_file.txt -in=%a 0:02.24 elapsed, 0.10 user, 0.08 system, 8% CPU, (0 major + 3676 minor) faults, 0 io, 21932 rss
$ win_vim fat_file.txt -c:q 0:02.24 elapsed, 0.10 user, 0.08 system, 8% CPU, (0 major + 3676 minor) faults, 0 io, 21932 rss
$ win_emacs -execute '(insert-file-contents "fat_file.txt")' -kill 0:02.24 elapsed, 0.10 user, 0.08 system, 8% CPU, (0 major + 3676 minor) faults, 0 io, 21932 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "fat_file.txt") end-of-lisp $ win_emacs --script x.el 0:04.11 elapsed, 0.07 user, 0.07 system, 3% CPU, (0 major + 3717 minor) faults, 0 io, 21740 rss
$ win_nano fat_file.txt
0:9.04
pi-Linux:
$ time jot fat_file.txt -in=%a 0m41.855s
$ time vi fat_file.txt -c:q 3m49.014s
$ time emacs -execute '(insert-file-contents "fat_file.txt")' -kill Stopped after a few seconds with the message "Maximum buffer size exceeded"
$ cat - > x.el << end-of-lisp (insert-file-contents "fat_file.txt") end-of-lisp $ time emacs --script x.el Stopped with the message "Maximum buffer size exceeded"
$ time nano fat_file.txt
0m26.093s
This test is intended to compare performance for reading and searching files with long lines. The string is right at the end of the file so our editors must go through the whole file.
PC-linux:
$ time_trial jot fat_file.txt -in="%s=case 1; f/zzz/? %a;" 0:00.61 elapsed, 0.22 user, 0.38 system, 99% CPU, (0 major + 86778 minor) faults, 0 io, 294904 rss
$ time_trial vim fat_file.txt -c/zzz/ +:q 0:02.08 elapsed, 1.62 user, 0.36 system, 95% CPU, (20 major + 80865 minor) faults, 0 io, 381104 rss
$ time_trial emacs -execute '(insert-file-contents "fat_file.txt")' -execute '(search-forward "zzz")' -kill 0:03.42 elapsed, 3.09 user, 0.31 system, 99% CPU, (0 major + 92286 minor) faults, 0 io, 318980 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "fat_file.txt") (search-forward "zzz") end-of-lisp $ time_trial emacs --script x.el 0:01.53 elapsed, 1.20 user, 0.31 system, 99% CPU, (0 major + 77445 minor) faults, 0 io, 350104 rss
$ time_trial nano fat_file.txt
0:13.78 elapsed, 5.56 user, 0.31 system, 42% CPU, (0 major + 75148 minor) faults, 0 io, 303068 rss
PC-Windows:
$ win_jot fat_file.txt -in="%s=case 1; f/zzz/? %a;" 0:02.47 elapsed, 0.10 user, 0.09 system, 7% CPU, (0 major + 3864 minor) faults, 0 io, 21736 rss
$ win_vim fat_file.txt -c/zzz/ +:q 0:07.53 elapsed, 0.10 user, 0.10 system, 2% CPU, (0 major + 3870 minor) faults, 0 io, 21620 rss
$ win_emacs -execute '(insert-file-contents "fat_file.txt")' -execute '(search-forward "zzz")' -kill 0:06.46 elapsed, 0.07 user, 0.09 system, 2% CPU, (2 major + 3714 minor) faults, 248 io, 21692 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "fat_file.txt") (search-forward "zzz") end-of-lisp $ win_emacs --script x.el 0:04.55 elapsed, 0.08 user, 0.06 system, 3% CPU, (0 major + 3683 minor) faults, 0 io, 21972 rss
$ win_nano fat_file.txt
0:39.0
pi-linux:
$ time jot fat_file.txt -in="%s=case 1; f/zzz/? %a;" 0m38.434s
$ time vi fat_file.txt -c/zzz/ +:q 3m40.809s
$ time emacs -execute '(insert-file-contents "fat_file.txt")' -execute '(search-forward "zzz")' -kill "Maximum buffer size exceeded"
$ cat - > x.el << end-of-lisp (insert-file-contents "fat_file.txt") (search-forward "zzz") end-of-lisp $ time emacs --script x.el "Maximum buffer size exceeded"
$ time nano fat_file.txt
This test compares the performance for searching and replacing with a new string of the same size. We're searching for "99" because there so too many instances of "00" all but one of the editors crashed or exceeded the 30 minute limit. That editor was, of course, jot which, if you're interested, did the lot in under 3 seconds.
Substituting a string of the same size as the original should be the simplest search-and-replace situation since no new memory or byte shifting is required. Later sections will repeat these tests but for both longer and shorter substitutions.
PC-linux:
$ time_trial jot fat_file.txt -in="%s=case 1; (f/99/s/zz/)0 %a" 0:00.85 elapsed, 0.47 user, 0.37 system, 99% CPU, (0 major + 86779 minor) faults, 0 io, 294860 rss
$ time_trial vim fat_file.txt -c:%s/99/zz/g +:q! 0:37.27 elapsed, 36.54 user, 0.49 system, 99% CPU, (2 major + 162374 minor) faults, 64 io, 599368 rss
$ time_trial emacs -execute '(insert-file-contents "fat_file.txt")' -execute '(replace-string "99" "zz")' -kill 0:06.37 elapsed, 5.80 user, 0.40 system, 97% CPU, (86 major + 85713 minor) faults, 1480 io, 400676 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "fat_file.txt") (replace-string "99" "zz") end-of-lisp $ time_trial emacs --script x.el 0:02.23 elapsed, 1.89 user, 0.32 system, 99% CPU, (0 major + 78984 minor) faults, 0 io, 356752 rss
$ time_trial nano fat_file.txt
It crashed the X session.
PC-windows:
$ win_jot fat_file.txt -in="%s=case 1; (f/99/s/zz/)0 %a" 0:02.19 elapsed, 0.08 user, 0.07 system, 7% CPU, (0 major + 3703 minor) faults, 0 io, 21820 rss
$ win_vim fat_file.txt -c:%s/99/zz/g +:q! 3:16.35 elapsed, 0.09 user, 0.09 system, 0% CPU, (0 major + 3853 minor) faults, 0 io, 21868 rss
$ win_emacs -execute '(insert-file-contents "fat_file.txt")' -execute '(replace-string "99" "zz")' -kill 0:11.22 elapsed, 0.07 user, 0.08 system, 1% CPU, (0 major + 3711 minor) faults, 0 io, 21708 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "fat_file.txt") (replace-string "99" "zz") end-of-lisp $ win_emacs --script x.el 0:05.35 elapsed, 0.09 user, 0.08 system, 3% CPU, (0 major + 3706 minor) faults, 0 io, 21848 rss
$ win_nano fat_file.txt
Fails after 28 seconds with "Nano is out of memory"
pi-linux:
$ time jot fat_file.txt -in="%s=case 1; (f/99/s/zz/)0 %a" 0m15.362s
$ time vi fat_file.txt -c:%s/99/zz/g +:q! 11m3.558s
$ time emacs -execute '(insert-file-contents "fat_file.txt")' -execute '(replace-string "99" "zz")' -kill 1m13.748s
$ cat - > x.el << end-of-lisp (insert-file-contents "fat_file.txt") (replace-string "99" "zz") end-of-lisp $ time emacs --script x.el 0m17.509s
$ time nano fat_file.txt
Crashed after a few minutes.
This time the substitute string is a bit longer than the original.
PC-linux:
$ time_trial jot fat_file.txt -in="%s=case 1; (f/99/s/abcdefghi/)0 %a" 1:14.89 elapsed, 54.44 user, 20.01 system, 99% CPU, (0 major + 9890771 minor) faults, 0 io, 325572 rss
$ time_trial vim fat_file.txt -c:%s/99/abcdefghi/g +:q! 0:39.75 elapsed, 38.99 user, 0.52 system, 99% CPU, (0 major + 166002 minor) faults, 0 io, 601888 rss
$ time_trial emacs -execute '(insert-file-contents "fat_file.txt")' -execute '(replace-string "99" "abcdefghi")' -kill 0:06.42 elapsed, 5.91 user, 0.38 system, 98% CPU, (20 major + 86843 minor) faults, 0 io, 405448 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "fat_file.txt") (replace-string "99" "abcdefghi") end-of-lisp $ time_trial emacs --script x.el 0:02.30 elapsed, 1.96 user, 0.32 system, 99% CPU, (0 major + 80121 minor) faults, 0 io, 361448 rss
$ time_trial nano fat_file.txt
Crashed the X session.
PC-windows:
$ win_jot fat_file.txt -in="%s=case 1; (f/99/s/abcdefghi/)0 %a" 6:40.53 elapsed, 0.10 user, 0.08 system, 0% CPU, (0 major + 3698 minor) faults, 0 io, 21836 rss
$ win_vim fat_file.txt -c:%s/99/abcdefghi/g +:q! 3:25.46 elapsed, 0.08 user, 0.09 system, 0% CPU, (0 major + 3701 minor) faults, 0 io, 21752 rss
$ win_emacs -execute '(insert-file-contents "fat_file.txt")' -execute '(replace-string "99" "abcdefghi")' -kill 0:14.25 elapsed, 0.06 user, 0.07 system, 1% CPU, (0 major + 3713 minor) faults, 0 io, 21796 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "fat_file.txt") (replace-string "99" "abcdefghi") end-of-lisp $ win_emacs --script x.el 0:06.16 elapsed, 0.08 user, 0.09 system, 2% CPU, (0 major + 3705 minor) faults, 0 io, 21712 rss
$ win_nano fat_file.txt
Skipped as nano will only crash X.
pi-Linux:
$ time jot fat_file.txt -in="%s=case 1; (f/99/s/abcdefghi/)0 %a" 38m10.914s
$ time vi fat_file.txt -c:%s/99/abcdefghi/g +:q! 11m29.315s
$ time emacs -execute '(insert-file-contents "fat_file.txt")' -execute '(replace-string "99" "abcdefghi")' -kill 1m0.651s
$ cat - > x.el << end-of-lisp (insert-file-contents "fat_file.txt") (replace-string "99" "abcdefghi") end-of-lisp $ time emacs --script x.el 0m15.442s
$ time nano fat_file.txt
Skipped
This time the substitute string is shorter than the original.
PC-linux:
$ time_trial jot fat_file.txt -in="%s=case 1; (f/99/s/a/)0 %a" 0:17.13 elapsed, 16.71 user, 0.35 system, 99% CPU, (0 major + 86780 minor) faults, 0 io, 294900 rss
$ time_trial vim fat_file.txt -c:%s/99/a/g +:q! 0:36.89 elapsed, 36.18 user, 0.48 system, 99% CPU, (0 major + 162374 minor) faults, 0 io, 599432 rss
$ time_trial emacs -execute '(insert-file-contents "fat_file.txt")' -execute '(replace-string "99" "a")' -kill 0:06.39 elapsed, 5.86 user, 0.38 system, 97% CPU, (60 major + 85716 minor) faults, 672 io, 400948 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "fat_file.txt") (replace-string "99" "a") end-of-lisp $ time_trial emacs --script x.el 0:02.20 elapsed, 1.88 user, 0.30 system, 99% CPU, (0 major + 78977 minor) faults, 0 io, 356920 rss
$ time_trial nano fat_file.txt
Skipped - nano always crashes while working with fat_file.txt
PC-windows:
$ win_jot fat_file.txt -in="%s=case 1; (f/99/s/a/)0 %a" 0:22.06 elapsed, 0.09 user, 0.09 system, 0% CPU, (0 major + 3705 minor) faults, 0 io, 21700 rss
$ win_vim fat_file.txt -c:%s/99/a/g +:q! 3:14.54 elapsed, 0.09 user, 0.07 system, 0% CPU, (0 major + 3701 minor) faults, 0 io, 21648 rss
$ win_emacs -execute '(insert-file-contents "fat_file.txt")' -execute '(replace-string "99" "a")' -kill 0:12.10 elapsed, 0.07 user, 0.07 system, 1% CPU, (0 major + 3693 minor) faults, 0 io, 21876 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "fat_file.txt") (replace-string "99" "a") end-of-lisp $ win_emacs --script x.el 0:05.61 elapsed, 0.08 user, 0.08 system, 3% CPU, (0 major + 4513 minor) faults, 0 io, 21056 rss
$ win_nano fat_file.txt
Skipped since fat_file.txt always crashes nano.
pi-linux:
$ time jot fat_file.txt -in="%s=case 1; (f/99/s/a/)0 %a" 2m23.176s
$ time vi fat_file.txt -c:%s/99/a/g +:q! 9m0.194s
$ time emacs -execute '(insert-file-contents "fat_file.txt")' -execute '(replace-string "99" "a")' -kill 0m45.784s
$ cat - > x.el << end-of-lisp (insert-file-contents "fat_file.txt") (replace-string "99" "a") end-of-lisp $ time emacs --script x.el 0m14.260s
$ time nano fat_file.txt
Skipped.
PC-Linux:
$ time_trial jot fat_file.txt -in="%s=case 1; m0 f-/aaa/? %a" 0:01.45 elapsed, 1.05 user, 0.39 system, 99% CPU, (0 major + 86778 minor) faults, 0 io, 294860 rss
$ time_trial vim fat_file.txt -c:$ +?aaa? +:q! 0:03.37 elapsed, 3.05 user, 0.30 system, 99% CPU, (0 major + 92286 minor) faults, 0 io, 318980 rss
$ time_trial emacs -execute '(insert-file-contents "fat_file.txt")' -execute '(goto-char (point-max))' -execute '(search-backward "aaa")' -kill 0:02.10 elapsed, 1.61 user, 0.37 system, 94% CPU, (20 major + 80880 minor) faults, 0 io, 381528 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "fat_file.txt") (goto-char (point-max)) (search-backward "aaa") end-of-lisp $ time_trial emacs --script x.el 0:01.59 elapsed, 1.27 user, 0.31 system, 99% CPU, (0 major + 77445 minor) faults, 0 io, 350160 rss
$ time_trial nano fat_file.txt
Skipped
PC-windows:
$ win_jot fat_file.txt -in="%s=case 1; m0 f-/aaa/? %a" 0:03.23 elapsed, 0.08 user, 0.10 system, 5% CPU, (0 major + 4517 minor) faults, 0 io, 21052 rss
$ win_vim fat_file.txt -c:$ +?aaa? +:q! 0:07.40 elapsed, 0.09 user, 0.09 system, 2% CPU, (0 major + 3703 minor) faults, 0 io, 21760 rss
$ win_emacs -execute '(insert-file-contents "fat_file.txt")' -execute '(goto-char (point-max))' -execute '(search-backward "aaa")' -kill 0:06.25 elapsed, 0.09 user, 0.08 system, 2% CPU, (0 major + 3697 minor) faults, 0 io, 21752 rss
$ cat - > x.el << end-of-lisp (insert-file-contents "fat_file.txt") (goto-char (point-max)) (search-backward "aaa") end-of-lisp $ win_emacs --script x.el 0:04.75 elapsed, 0.10 user, 0.08 system, 3% CPU, (0 major + 3710 minor) faults, 0 io, 21656 rss
$ win_nano fat_file.txt
On {Alt+b} it says: not supported on windows yet.
pi-Linux:
$ time jot fat_file.txt -in="%s=case 1; m0 f-/aaa/? %a" 0m13.025s
$ time vi fat_file.txt -c:$ +?aaa? +:q! 0m18.096s
$ time emacs -execute '(insert-file-contents "fat_file.txt")' -execute '(goto-char (point-max))' -execute '(search-backward "aaa")' -kill 0m12.628s
$ cat - > x.el << end-of-lisp (insert-file-contents "fat_file.txt") (goto-char (point-max)) (search-backward "aaa") end-of-lisp $ time emacs --script x.el 0m10.239s
$ time nano fat_file.txt
Skipped.
$ time_trial wineconsole "c:\Program Files (x86)"/Vim/vim82/vim t.t -c:q!
frets about the size of executables in this day and age but, if it were important, then jot would win hands down. All the other images have been stripped (symbolic debugging data removed) so, in the interests of comparing like with like, the size of a stripped jot with links to the sharable ncurses libraries has been included. A non-stripped jot with shared curses was used in the performance comparisons.
image-activation times, the biggest surprise was nano - one of the smallest executables but much slower than vim. Even, so this makes no real difference to the price of eggs. The biggest non-surprise was that emacs took considerably longer than all the others put together.
purposes includes the time taken to build the internal image structure, a fairly large file (about 1Gb) was used. Most of our editors were reasonably quick, although nano is just starting to look like the two-ounce weakling of the group.
structures. This, in turn, suggests, that for any given system, they should capable of swallowing much bigger files. The actual capacity, for any given system, depends on system tuning. Meanwhile jot and nano have about half the data density and we'd expect them to reach system-defined limits with files roughly half the size of the vims and emacs. On my PC, vim and emacs can (eventually) load a 5GB file and jot and nano can not.
Jot's internal record structure facilitates jot tags, hashtable jumps, sorting and various other useful features including support for files too big for vim to swallow. Yet the fact remains - vim can load 10GB files and jot can not.
something with our file image, search it for something, in this case, we see a continuation of the trend established in the previous batch of tasks - namely that nano struggles with big files. The rest of our interactive editors all performed reasonably well, the non-interactive emacs being the star performer.
vim and emacs each have a built-in function for doing global search and replace. It would seem reasonable to expect these to outperform the jot interpretive approach - which essentially consists of find-string, replace-string and repeat to exhaustion. So how surprising was it that jot came an easy first in this task - by a country mile, in the case of emacs. Poor old nano, unfortunately, fell by the wayside.
previous task, the substituted string was the same length as the search string. This is not always the case, when the text shrinks or grows, text may have to be shifted, depending on the internal data structure. Furthermore, allowing the text to grow implies that more memory must be allocated and efficiently deployed. The next task is designed to sort the men from the boys. This time vim and emacs were all more-or-less comparable with jot an order of magnitude faster and, oh dear! nano...
shows that jot's regular-expression engine is far less speedy than vim's. The non-interactive emacs managed to finish well ahead of the interactive version both emacs times being comparable to jot's.
that backwards-searching performs differently to forwards searching - thes results should be compared to the earlier section Loading a big file and searching forwards. Interestingly, emacs was much slower in reverse, the other editors were pretty much the same in either direction.
special difficulties for editors. All of our editors swallowed this moderately large file (100MB) in good time.
reasonably good time although, some, less-so than others.
this task, our editors were instructed to change all instances of "00" to "zz". Only jot and the lisp-script emacs managed to complete this task in under 30 minutes, vim fell over as did the usual suspect: nano.
test we set our editors the task of change every instance of the string "99" to "abcdefghi". Since there are quite a lot less of these, the editors might find this slightly easier. Most editors have to work harder when the new string is a different size to the original, especially when it's longer. The editors all completed this in reasonable time, once again, nano was far behind the main pack.
swallowed this file in reasonable time, although nano was significantly slower than the rest.
the interactive emacs session, nano was much slower.
was quite a lot faster, nano crashed but vim, gvim and interactive-emacs all got there in the end.
Now performing substitutions on very long lines can present difficulties for text editors that rely in text shuffling as line-lengths change - jot is one such.
For this relatively small file (only about 100MB) jot won hands down, but the tables were turned later when they had to do the same thing but with a much bigger file.
options for %S, %B, %Q and
%H commands.
http://www.adp-gmbh.ch/vim/scripting/built_in_functions.html)
these in other people's efforts.
There were persistent problems with editors crashing on tasks they usually have no trouble performing. Also nano seemed to be particularly crashy when attempting the long-line file tasks. It was experimentally determined that nano, even if it did not crash itself, was somehow cause subsequent programmes to crash some time after nano had, apparently successfully, finished it's task and exited - maybe a memory leak?
The editors were run manually with the time utility monitoring a few system parameters while they did a global search and replace in the same file with very long lines. The test_file.txt used was a shortened version of fat_file.txt just under 8Mb with lines of up to 3mb long. The editors task was a global substitution - changing the 603 instances of "99" to "abcdefghi",
/usr/bin/time -f " %E elapsed, %U user, %S system, %P CPU, (%F major + %R minor) faults, %I io, %M rss" jot test_file.txt -quiet -in="%f= -global_substitute=abcdefghi 99; %a0;"
0:00.12 elapsed, 0.08 user, 0.03 system, 99% CPU, (0 major + 4793 minor) faults, 0 io, 16764 rss
/usr/bin/time -f " %E elapsed, %U user, %S system, %P CPU, (%F major + %R minor) faults, %I io, %M rss" vim test_file.txt -c:%s/99/abcdefghi/g +:q!
0:00.74 elapsed, 0.69 user, 0.04 system, 99% CPU, (0 major + 14512 minor) faults, 0 io, 38760 rss
/usr/bin/time -f " %E elapsed, %U user, %S system, %P CPU, (%F major + %R minor) faults, %I io, %M rss" emacs -execute '(insert-file-contents "test_file.txt")' -execute '(replace-string "99" "abcdefghi")' -kill
0:00.83 elapsed, 0.60 user, 0.09 system, 83% CPU, (20 major + 10360 minor) faults, 0 io, 99372 rss
/usr/bin/time -f " %E elapsed, %U user, %S system, %P CPU, (%F major + %R minor) faults, %I io, %M rss" ecce test_file.txt -command "(f/99/s/a/)0" -command "%a"
... 0:00.14 elapsed, 0.12 user, 0.01 system, 98% CPU, (0 major + 3914 minor) faults, 0 io, 16720 rss
/usr/bin/time -f " %E elapsed, %U user, %S system, %P CPU, (%F major + %R minor) faults, %I io, %M rss" nano test_file.txt
3:35.64 elapsed, 195.80 user, 1.00 system, 91% CPU, (0 major + 488202 minor) faults, 0 io, 1937276 rss
Name Elapsed User System CPU Major Minor IO RSS
00.12 0.08 0.03 99% 0 4793 0 16764
00.74 0.69 0.04 99% 0 14512 0 38760
00.83 0.60 0.09 83% 20 10360 0 99372
00.14 0.12 0.01 98% 0 3914 0 16720
35.64 195.80 1.00 91% 0 488202 0 1937276
Phew!!!! nano's main claim my be that it's small, friendly and lightweight but, an RSS of 1937276 for a 8Mb file, that's neither small or lightweight and definitely unfriendly - one might easily mistake it for a memory-gobbling monster.