nimc.rst 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684
  1. ===================================
  2. Nim Compiler User Guide
  3. ===================================
  4. :Author: Andreas Rumpf
  5. :Version: |nimversion|
  6. .. contents::
  7. "Look at you, hacker. A pathetic creature of meat and bone, panting and
  8. sweating as you run through my corridors. How can you challenge a perfect,
  9. immortal machine?"
  10. Introduction
  11. ============
  12. This document describes the usage of the *Nim compiler*
  13. on the different supported platforms. It is not a definition of the Nim
  14. programming language (which is covered in the `manual <manual.html>`_).
  15. Nim is free software; it is licensed under the
  16. `MIT License <http://www.opensource.org/licenses/mit-license.php>`_.
  17. Compiler Usage
  18. ==============
  19. Command line switches
  20. ---------------------
  21. Basic command line switches are:
  22. Usage:
  23. .. include:: basicopt.txt
  24. ----
  25. Advanced command line switches are:
  26. .. include:: advopt.txt
  27. List of warnings
  28. ----------------
  29. Each warning can be activated individually with ``--warning[NAME]:on|off`` or
  30. in a ``push`` pragma.
  31. ========================== ============================================
  32. Name Description
  33. ========================== ============================================
  34. CannotOpenFile Some file not essential for the compiler's
  35. working could not be opened.
  36. OctalEscape The code contains an unsupported octal
  37. sequence.
  38. Deprecated The code uses a deprecated symbol.
  39. ConfigDeprecated The project makes use of a deprecated config
  40. file.
  41. SmallLshouldNotBeUsed The letter 'l' should not be used as an
  42. identifier.
  43. EachIdentIsTuple The code contains a confusing ``var``
  44. declaration.
  45. User Some user defined warning.
  46. ========================== ============================================
  47. List of hints
  48. -------------
  49. Each hint can be activated individually with ``--hint[NAME]:on|off`` or in a
  50. ``push`` pragma.
  51. ========================== ============================================
  52. Name Description
  53. ========================== ============================================
  54. CC Shows when the C compiler is called.
  55. CodeBegin
  56. CodeEnd
  57. CondTrue
  58. Conf A config file was loaded.
  59. ConvToBaseNotNeeded
  60. ConvFromXtoItselfNotNeeded
  61. Dependency
  62. Exec Program is executed.
  63. ExprAlwaysX
  64. ExtendedContext
  65. GCStats Dumps statistics about the Garbage Collector.
  66. GlobalVar Shows global variables declarations.
  67. LineTooLong Line exceeds the maximum length.
  68. Link Linking phase.
  69. Name
  70. Path Search paths modifications.
  71. Pattern
  72. Performance
  73. Processing Artifact being compiled.
  74. QuitCalled
  75. Source The source line that triggered a diagnostic
  76. message.
  77. StackTrace
  78. Success, SuccessX Successful compilation of a library or a binary.
  79. User
  80. UserRaw
  81. XDeclaredButNotUsed Unused symbols in the code.
  82. ========================== ============================================
  83. Verbosity levels
  84. ----------------
  85. ===== ============================================
  86. Level Description
  87. ===== ============================================
  88. 0 Minimal output level for the compiler.
  89. 1 Displays compilation of all the compiled files, including those imported
  90. by other modules or through the `compile pragma
  91. <manual.html#implementation-specific-pragmas-compile-pragma>`_.
  92. This is the default level.
  93. 2 Displays compilation statistics, enumerates the dynamic
  94. libraries that will be loaded by the final binary and dumps to
  95. standard output the result of applying `a filter to the source code
  96. <filters.html>`_ if any filter was used during compilation.
  97. 3 In addition to the previous levels dumps a debug stack trace
  98. for compiler developers.
  99. ===== ============================================
  100. Compile time symbols
  101. --------------------
  102. Through the ``-d:x`` or ``--define:x`` switch you can define compile time
  103. symbols for conditional compilation. The defined switches can be checked in
  104. source code with the `when statement
  105. <manual.html#statements-and-expressions-when-statement>`_ and
  106. `defined proc <system.html#defined,untyped>`_. The typical use of this switch is
  107. to enable builds in release mode (``-d:release``) where optimizations are
  108. enabled for better performance. Another common use is the ``-d:ssl`` switch to
  109. activate SSL sockets.
  110. Additionally, you may pass a value along with the symbol: ``-d:x=y``
  111. which may be used in conjunction with the `compile time define
  112. pragmas<manual.html#implementation-specific-pragmas-compile-time-define-pragmas>`_
  113. to override symbols during build time.
  114. Compile time symbols are completely **case insensitive** and underscores are
  115. ignored too. ``--define:FOO`` and ``--define:foo`` are identical.
  116. Compile time symbols starting with the ``nim`` prefix are reserved for the
  117. implementation and should not be used elsewhere.
  118. Configuration files
  119. -------------------
  120. **Note:** The *project file name* is the name of the ``.nim`` file that is
  121. passed as a command line argument to the compiler.
  122. The ``nim`` executable processes configuration files in the following
  123. directories (in this order; later files overwrite previous settings):
  124. 1) ``$nim/config/nim.cfg``, ``/etc/nim/nim.cfg`` (UNIX) or ``<Nim's installation directory>\config\nim.cfg`` (Windows). This file can be skipped with the ``--skipCfg`` command line option.
  125. 2) If environment variable ``XDG_CONFIG_HOME`` is defined, ``$XDG_CONFIG_HOME/nim/nim.cfg`` or ``~/.config/nim/nim.cfg`` (POSIX) or ``%APPDATA%/nim/nim.cfg`` (Windows). This file can be skipped with the ``--skipUserCfg`` command line option.
  126. 3) ``$parentDir/nim.cfg`` where ``$parentDir`` stands for any parent directory of the project file's path. These files can be skipped with the ``--skipParentCfg`` command line option.
  127. 4) ``$projectDir/nim.cfg`` where ``$projectDir`` stands for the project file's path. This file can be skipped with the ``--skipProjCfg`` command line option.
  128. 5) A project can also have a project specific configuration file named ``$project.nim.cfg`` that resides in the same directory as ``$project.nim``. This file can be skipped with the ``--skipProjCfg`` command line option.
  129. Command line settings have priority over configuration file settings.
  130. The default build of a project is a `debug build`:idx:. To compile a
  131. `release build`:idx: define the ``release`` symbol::
  132. nim c -d:release myproject.nim
  133. To compile a `dangerous release build`:idx: define the ``danger`` symbol::
  134. nim c -d:danger myproject.nim
  135. Search path handling
  136. --------------------
  137. Nim has the concept of a global search path (PATH) that is queried to
  138. determine where to find imported modules or include files. If multiple files are
  139. found an ambiguity error is produced.
  140. ``nim dump`` shows the contents of the PATH.
  141. However before the PATH is used the current directory is checked for the
  142. file's existence. So if PATH contains ``$lib`` and ``$lib/bar`` and the
  143. directory structure looks like this::
  144. $lib/x.nim
  145. $lib/bar/x.nim
  146. foo/x.nim
  147. foo/main.nim
  148. other.nim
  149. And ``main`` imports ``x``, ``foo/x`` is imported. If ``other`` imports ``x``
  150. then both ``$lib/x.nim`` and ``$lib/bar/x.nim`` match but ``$lib/x.nim`` is used
  151. as it is the first match.
  152. Generated C code directory
  153. --------------------------
  154. The generated files that Nim produces all go into a subdirectory called
  155. ``nimcache``. Its full path is
  156. - ``$XDG_CACHE_HOME/nim/$projectname(_r|_d)`` or ``~/.cache/nim/$projectname(_r|_d)``
  157. on Posix
  158. - ``$HOME/nimcache/$projectname(_r|_d)`` on Windows.
  159. The ``_r`` suffix is used for release builds, ``_d`` is for debug builds.
  160. This makes it easy to delete all generated files.
  161. The ``--nimcache``
  162. `compiler switch <#compiler-usage-command-line-switches>`_ can be used to
  163. to change the ``nimcache`` directory.
  164. However, the generated C code is not platform independent. C code generated for
  165. Linux does not compile on Windows, for instance. The comment on top of the
  166. C file lists the OS, CPU and CC the file has been compiled for.
  167. Compiler Selection
  168. ==================
  169. To change the compiler from the default compiler (at the command line)::
  170. nim c --cc:llvm_gcc --compile_only myfile.nim
  171. This uses the configuration defined in ``config\nim.cfg`` for ``lvm_gcc``.
  172. If nimcache already contains compiled code from a different compiler for the same project,
  173. add the ``-f`` flag to force all files to be recompiled.
  174. The default compiler is defined at the top of ``config\nim.cfg``.
  175. Changing this setting affects the compiler used by ``koch`` to (re)build Nim.
  176. To use the ``CC`` environment variable, use ``nim c --cc:env myfile.nim``. To use the
  177. ``CXX`` environment variable, use ``nim cpp --cc:env myfile.nim``. ``--cc:env`` is available
  178. since Nim version 1.4.
  179. Cross compilation
  180. =================
  181. To cross compile, use for example::
  182. nim c --cpu:i386 --os:linux --compileOnly --genScript myproject.nim
  183. Then move the C code and the compile script ``compile_myproject.sh`` to your
  184. Linux i386 machine and run the script.
  185. Another way is to make Nim invoke a cross compiler toolchain::
  186. nim c --cpu:arm --os:linux myproject.nim
  187. For cross compilation, the compiler invokes a C compiler named
  188. like ``$cpu.$os.$cc`` (for example arm.linux.gcc) and the configuration
  189. system is used to provide meaningful defaults. For example for ``ARM`` your
  190. configuration file should contain something like::
  191. arm.linux.gcc.path = "/usr/bin"
  192. arm.linux.gcc.exe = "arm-linux-gcc"
  193. arm.linux.gcc.linkerexe = "arm-linux-gcc"
  194. Cross compilation for Windows
  195. =============================
  196. To cross compile for Windows from Linux or macOS using the MinGW-w64 toolchain::
  197. nim c -d:mingw myproject.nim
  198. Use ``--cpu:i386`` or ``--cpu:amd64`` to switch the CPU architecture.
  199. The MinGW-w64 toolchain can be installed as follows::
  200. Ubuntu: apt install mingw-w64
  201. CentOS: yum install mingw32-gcc | mingw64-gcc - requires EPEL
  202. OSX: brew install mingw-w64
  203. Cross compilation for Android
  204. =============================
  205. There are two ways to compile for Android: terminal programs (Termux) and with
  206. the NDK (Android Native Development Kit).
  207. First one is to treat Android as a simple Linux and use
  208. `Termux <https://wiki.termux.com>`_ to connect and run the Nim compiler
  209. directly on android as if it was Linux. These programs are console only
  210. programs that can't be distributed in the Play Store.
  211. Use regular ``nim c`` inside termux to make Android terminal programs.
  212. Normal Android apps are written in Java, to use Nim inside an Android app
  213. you need a small Java stub that calls out to a native library written in
  214. Nim using the `NDK <https://developer.android.com/ndk>`_. You can also use
  215. `native-acitivty <https://developer.android.com/ndk/samples/sample_na>`_
  216. to have the Java stub be auto generated for you.
  217. Use ``nim c -c --cpu:arm --os:android -d:androidNDK --noMain:on`` to
  218. generate the C source files you need to include in your Android Studio
  219. project. Add the generated C files to CMake build script in your Android
  220. project. Then do the final compile with Android Studio which uses Gradle
  221. to call CMake to compile the project.
  222. Because Nim is part of a library it can't have its own c style ``main()``
  223. so you would need to define your own ``android_main`` and init the Java
  224. environment, or use a library like SDL2 or GLFM to do it. After the Android
  225. stuff is done, it's very important to call ``NimMain()`` in order to
  226. initialize Nim's garbage collector and to run the top level statements
  227. of your program.
  228. .. code-block:: Nim
  229. proc NimMain() {.importc.}
  230. proc glfmMain*(display: ptr GLFMDisplay) {.exportc.} =
  231. NimMain() # initialize garbage collector memory, types and stack
  232. Cross compilation for iOS
  233. =========================
  234. To cross compile for iOS you need to be on a MacOS computer and use XCode.
  235. Normal languages for iOS development are Swift and Objective C. Both of these
  236. use LLVM and can be compiled into object files linked together with C, C++
  237. or Objective C code produced by Nim.
  238. Use ``nim c -c --os:ios --noMain:on`` to generate C files and include them in
  239. your XCode project. Then you can use XCode to compile, link, package and
  240. sign everything.
  241. Because Nim is part of a library it can't have its own c style ``main()`` so you
  242. would need to define `main` that calls ``autoreleasepool`` and
  243. ``UIApplicationMain`` to do it, or use a library like SDL2 or GLFM. After
  244. the iOS setup is done, it's very important to call ``NimMain()`` in order to
  245. initialize Nim's garbage collector and to run the top level statements
  246. of your program.
  247. .. code-block:: Nim
  248. proc NimMain() {.importc.}
  249. proc glfmMain*(display: ptr GLFMDisplay) {.exportc.} =
  250. NimMain() # initialize garbage collector memory, types and stack
  251. Note: XCode's "make clean" gets confused about the generated nim.c files,
  252. so you need to clean those files manually to do a clean build.
  253. Cross compilation for Nintendo Switch
  254. =====================================
  255. Simply add --os:nintendoswitch
  256. to your usual ``nim c`` or ``nim cpp`` command and set the ``passC``
  257. and ``passL`` command line switches to something like:
  258. .. code-block:: console
  259. nim c ... --passC="-I$DEVKITPRO/libnx/include" ...
  260. --passL="-specs=$DEVKITPRO/libnx/switch.specs -L$DEVKITPRO/libnx/lib -lnx"
  261. or setup a nim.cfg file like so:
  262. .. code-block:: Nim
  263. #nim.cfg
  264. --passC="-I$DEVKITPRO/libnx/include"
  265. --passL="-specs=$DEVKITPRO/libnx/switch.specs -L$DEVKITPRO/libnx/lib -lnx"
  266. The DevkitPro setup must be the same as the default with their new installer
  267. `here for Mac/Linux <https://github.com/devkitPro/pacman/releases>`_ or
  268. `here for Windows <https://github.com/devkitPro/installer/releases>`_.
  269. For example, with the above mentioned config::
  270. nim c --os:nintendoswitch switchhomebrew.nim
  271. This will generate a file called ``switchhomebrew.elf`` which can then be turned into
  272. an nro file with the ``elf2nro`` tool in the DevkitPro release. Examples can be found at
  273. `the nim-libnx github repo <https://github.com/jyapayne/nim-libnx.git>`_.
  274. There are a few things that don't work because the DevkitPro libraries don't support them.
  275. They are:
  276. 1. Waiting for a subprocess to finish. A subprocess can be started, but right
  277. now it can't be waited on, which sort of makes subprocesses a bit hard to use
  278. 2. Dynamic calls. DevkitPro libraries have no dlopen/dlclose functions.
  279. 3. Command line parameters. It doesn't make sense to have these for a console
  280. anyways, so no big deal here.
  281. 4. mqueue. Sadly there are no mqueue headers.
  282. 5. ucontext. No headers for these either. No coroutines for now :(
  283. 6. nl_types. No headers for this.
  284. DLL generation
  285. ==============
  286. Nim supports the generation of DLLs. However, there must be only one
  287. instance of the GC per process/address space. This instance is contained in
  288. ``nimrtl.dll``. This means that every generated Nim DLL depends
  289. on ``nimrtl.dll``. To generate the "nimrtl.dll" file, use the command::
  290. nim c -d:release lib/nimrtl.nim
  291. To link against ``nimrtl.dll`` use the command::
  292. nim c -d:useNimRtl myprog.nim
  293. **Note**: Currently the creation of ``nimrtl.dll`` with thread support has
  294. never been tested and is unlikely to work!
  295. Additional compilation switches
  296. ===============================
  297. The standard library supports a growing number of ``useX`` conditional defines
  298. affecting how some features are implemented. This section tries to give a
  299. complete list.
  300. ====================== =========================================================
  301. Define Effect
  302. ====================== =========================================================
  303. ``release`` Turns on the optimizer.
  304. More aggressive optimizations are possible, eg:
  305. ``--passC:-ffast-math`` (but see issue #10305)
  306. ``danger`` Turns off all runtime checks and turns on the optimizer.
  307. ``useFork`` Makes ``osproc`` use ``fork`` instead of ``posix_spawn``.
  308. ``useNimRtl`` Compile and link against ``nimrtl.dll``.
  309. ``useMalloc`` Makes Nim use C's `malloc`:idx: instead of Nim's
  310. own memory manager, albeit prefixing each allocation with
  311. its size to support clearing memory on reallocation.
  312. This only works with ``gc:none`` and
  313. with ``--newruntime``.
  314. ``useRealtimeGC`` Enables support of Nim's GC for *soft* realtime
  315. systems. See the documentation of the `gc <gc.html>`_
  316. for further information.
  317. ``logGC`` Enable GC logging to stdout.
  318. ``nodejs`` The JS target is actually ``node.js``.
  319. ``ssl`` Enables OpenSSL support for the sockets module.
  320. ``memProfiler`` Enables memory profiling for the native GC.
  321. ``uClibc`` Use uClibc instead of libc. (Relevant for Unix-like OSes)
  322. ``checkAbi`` When using types from C headers, add checks that compare
  323. what's in the Nim file with what's in the C header.
  324. This may become enabled by default in the future.
  325. ``tempDir`` This symbol takes a string as its value, like
  326. ``--define:tempDir:/some/temp/path`` to override the
  327. temporary directory returned by ``os.getTempDir()``.
  328. The value **should** end with a directory separator
  329. character. (Relevant for the Android platform)
  330. ``useShPath`` This symbol takes a string as its value, like
  331. ``--define:useShPath:/opt/sh/bin/sh`` to override the
  332. path for the ``sh`` binary, in cases where it is not
  333. located in the default location ``/bin/sh``.
  334. ``noSignalHandler`` Disable the crash handler from ``system.nim``.
  335. ``globalSymbols`` Load all ``{.dynlib.}`` libraries with the ``RTLD_GLOBAL``
  336. flag on Posix systems to resolve symbols in subsequently
  337. loaded libraries.
  338. ====================== =========================================================
  339. Additional Features
  340. ===================
  341. This section describes Nim's additional features that are not listed in the
  342. Nim manual. Some of the features here only make sense for the C code
  343. generator and are subject to change.
  344. LineDir option
  345. --------------
  346. The ``lineDir`` option can be turned on or off. If turned on the
  347. generated C code contains ``#line`` directives. This may be helpful for
  348. debugging with GDB.
  349. StackTrace option
  350. -----------------
  351. If the ``stackTrace`` option is turned on, the generated C contains code to
  352. ensure that proper stack traces are given if the program crashes or an
  353. uncaught exception is raised.
  354. LineTrace option
  355. ----------------
  356. The ``lineTrace`` option implies the ``stackTrace`` option. If turned on,
  357. the generated C contains code to ensure that proper stack traces with line
  358. number information are given if the program crashes or an uncaught exception
  359. is raised.
  360. DynlibOverride
  361. ==============
  362. By default Nim's ``dynlib`` pragma causes the compiler to generate
  363. ``GetProcAddress`` (or their Unix counterparts)
  364. calls to bind to a DLL. With the ``dynlibOverride`` command line switch this
  365. can be prevented and then via ``--passL`` the static library can be linked
  366. against. For instance, to link statically against Lua this command might work
  367. on Linux::
  368. nim c --dynlibOverride:lua --passL:liblua.lib program.nim
  369. Backend language options
  370. ========================
  371. The typical compiler usage involves using the ``compile`` or ``c`` command to
  372. transform a ``.nim`` file into one or more ``.c`` files which are then
  373. compiled with the platform's C compiler into a static binary. However there
  374. are other commands to compile to C++, Objective-C or JavaScript. More details
  375. can be read in the `Nim Backend Integration document <backends.html>`_.
  376. Nim documentation tools
  377. =======================
  378. Nim provides the `doc`:idx: and `doc2`:idx: commands to generate HTML
  379. documentation from ``.nim`` source files. Only exported symbols will appear in
  380. the output. For more details `see the docgen documentation <docgen.html>`_.
  381. Nim idetools integration
  382. ========================
  383. Nim provides language integration with external IDEs through the
  384. idetools command. See the documentation of `idetools <idetools.html>`_
  385. for further information.
  386. ..
  387. Nim interactive mode
  388. ====================
  389. The Nim compiler supports an interactive mode. This is also known as
  390. a `REPL`:idx: (*read eval print loop*). If Nim has been built with the
  391. ``-d:nimUseLinenoise`` switch, it uses the GNU readline library for terminal
  392. input management. To start Nim in interactive mode use the command
  393. ``nim secret``. To quit use the ``quit()`` command. To determine whether an input
  394. line is an incomplete statement to be continued these rules are used:
  395. 1. The line ends with ``[-+*/\\<>!\?\|%&$@~,;:=#^]\s*$`` (operator symbol followed by optional whitespace).
  396. 2. The line starts with a space (indentation).
  397. 3. The line is within a triple quoted string literal. However, the detection
  398. does not work if the line contains more than one ``"""``.
  399. Nim for embedded systems
  400. ========================
  401. While the default Nim configuration is targeted for optimal performance on
  402. modern PC hardware and operating systems with ample memory, it is very well
  403. possible to run Nim code and a good part of the Nim standard libraries on small
  404. embedded microprocessors with only a few kilobytes of memory.
  405. A good start is to use the ``any`` operating target together with the
  406. ``malloc`` memory allocator and the ``arc`` garbage collector. For example:
  407. ``nim c --os:any --gc:arc -d:useMalloc [...] x.nim``
  408. - ``--gc:arc`` will enable the reference counting memory management instead
  409. of the default garbage collector. This enables Nim to use heap memory which
  410. is required for strings and seqs, for example.
  411. - The ``--os:any`` target makes sure Nim does not depend on any specific
  412. operating system primitives. Your platform should support only some basic
  413. ANSI C library ``stdlib`` and ``stdio`` functions which should be available
  414. on almost any platform.
  415. - The ``-d:useMalloc`` option configures Nim to use only the standard C memory
  416. manage primitives ``malloc()``, ``free()``, ``realloc()``.
  417. If your platform does not provide these functions it should be trivial to
  418. provide an implementation for them and link these to your program.
  419. For targets with very restricted memory, it might be beneficial to pass some
  420. additional flags to both the Nim compiler and the C compiler and/or linker
  421. to optimize the build for size. For example, the following flags can be used
  422. when targeting a gcc compiler:
  423. ``--opt:size --passC:-flto --passL:-flto``
  424. The ``--opt:size`` flag instructs Nim to optimize code generation for small
  425. size (with the help of the C compiler), the ``flto`` flags enable link-time
  426. optimization in the compiler and linker.
  427. Check the `Cross compilation` section for instructions how to compile the
  428. program for your target.
  429. Nim for realtime systems
  430. ========================
  431. See the documentation of Nim's soft realtime `GC <gc.html>`_ for further
  432. information.
  433. Signal handling in Nim
  434. ======================
  435. The Nim programming language has no concept of Posix's signal handling
  436. mechanisms. However, the standard library offers some rudimentary support
  437. for signal handling, in particular, segmentation faults are turned into
  438. fatal errors that produce a stack trace. This can be disabled with the
  439. ``-d:noSignalHandler`` switch.
  440. Optimizing for Nim
  441. ==================
  442. Nim has no separate optimizer, but the C code that is produced is very
  443. efficient. Most C compilers have excellent optimizers, so usually it is
  444. not needed to optimize one's code. Nim has been designed to encourage
  445. efficient code: The most readable code in Nim is often the most efficient
  446. too.
  447. However, sometimes one has to optimize. Do it in the following order:
  448. 1. switch off the embedded debugger (it is **slow**!)
  449. 2. turn on the optimizer and turn off runtime checks
  450. 3. profile your code to find where the bottlenecks are
  451. 4. try to find a better algorithm
  452. 5. do low-level optimizations
  453. This section can only help you with the last item.
  454. Optimizing string handling
  455. --------------------------
  456. String assignments are sometimes expensive in Nim: They are required to
  457. copy the whole string. However, the compiler is often smart enough to not copy
  458. strings. Due to the argument passing semantics, strings are never copied when
  459. passed to subroutines. The compiler does not copy strings that are a result from
  460. a procedure call, because the callee returns a new string anyway.
  461. Thus it is efficient to do:
  462. .. code-block:: Nim
  463. var s = procA() # assignment will not copy the string; procA allocates a new
  464. # string already
  465. However it is not efficient to do:
  466. .. code-block:: Nim
  467. var s = varA # assignment has to copy the whole string into a new buffer!
  468. For ``let`` symbols a copy is not always necessary:
  469. .. code-block:: Nim
  470. let s = varA # may only copy a pointer if it safe to do so
  471. If you know what you're doing, you can also mark single string (or sequence)
  472. objects as `shallow`:idx:\:
  473. .. code-block:: Nim
  474. var s = "abc"
  475. shallow(s) # mark 's' as shallow string
  476. var x = s # now might not copy the string!
  477. Usage of ``shallow`` is always safe once you know the string won't be modified
  478. anymore, similar to Ruby's `freeze`:idx:.
  479. The compiler optimizes string case statements: A hashing scheme is used for them
  480. if several different string constants are used. So code like this is reasonably
  481. efficient:
  482. .. code-block:: Nim
  483. case normalize(k.key)
  484. of "name": c.name = v
  485. of "displayname": c.displayName = v
  486. of "version": c.version = v
  487. of "os": c.oses = split(v, {';'})
  488. of "cpu": c.cpus = split(v, {';'})
  489. of "authors": c.authors = split(v, {';'})
  490. of "description": c.description = v
  491. of "app":
  492. case normalize(v)
  493. of "console": c.app = appConsole
  494. of "gui": c.app = appGUI
  495. else: quit(errorStr(p, "expected: console or gui"))
  496. of "license": c.license = UnixToNativePath(k.value)
  497. else: quit(errorStr(p, "unknown variable: " & k.key))