Skip to content

Allocation free printing: remove write(a: varargs[string]) #197

@krux02

Description

@krux02

Allocation is expensive. The costs are in allocation, deallocation, memory fragmentation (mostly a problem for long running server applications) and in garbage collector activity. Therefor I have a big interest to keep my main loop and especially tight loops free of allocations. Yet almost all string conversion and printing functions rely on temporary intermediate string objects (allocation). What I would like to have is a flexible printing mechanism, that does not allocate by construction.

There is a family of procs already existent in Nim that is almost already what I would like to have. The family of proc write*(f: File, r: float32) in io.nim. It works on overloads for different types, therefore it is extendable for custom types (unlike fprintf in C), it is implemented usually though with fprintf from C, which is completely allocation free. There is one big problem though: proc write*(f: File, a: varargs[string, `$`]) exists. This means expressions such as stdout.write(x) that would normally have no allocation at all, now might resolve to the varargs[string, `$`] overload without providing feedback to the programmer that this has happened. Variables of a custom types that do have an overload proc write*(f: File; a: CustomType) might still secretly resolve to the varargs[string, `$`] overload, because nim-lang/Nim#11225 has not been resolved yet.

Another big advantage of write over echo is, when it crashes when half of the line is printed, that half of the line is actually sent to stdout/stderr. Unlike echo where nothing is printed at all.

So my proposal is to remove proc write*(f: File, a: varargs[string, `$`]) from io.nim to have a style of writing to files and stdout that is free of allocation by construction.

Here is the PR for this RFC: nim-lang/Nim#13277

There is a related RFC targeting fewer allocations for string conversations:
#191

  • This RFC aims for 0 allocations for any printing command, where the RFC above aims for 1 allocation per printing command.
  • This RFC targets only printing to files, stdout and stdin. It does not solve priting to strings.
  • This RFC barely changes anything. And what it changes is currently not used in a lot of code (this means it should not cause any problems).
  • I don't know browser.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions