xoofx/Tomlyn

Provide `Async` methods

JamieMagee opened this issue · 4 comments

In the same way that System.Text.Json.JsonSerializer provides SerializeAsync and DeserializeAsync, is it possible to provide Async versions of ToModel and FromModel?

xoofx commented

Sorry, but I will have to decline this. 🙂

Async is so viral that I don't want to duplicate the code in Tomlyn, specially when TOML is mostly used for configuration files that are a few KB. That would be important if Tomlyn was used in the context of loading MB of files in and out, but I'm quite skeptical about the use case. Also async/await is usually performing worse than their sync counterpart because it allocates all around for continuations and there are less optimizations possible because of the generated stack machines. ValueTask doesn't help much there, it saves a few allocations but not that much. See for example my blog post here about Making Scriban async compatible (spoiler: async 3x slower)

It is not pretty, but if you desperately need async/await versions, you can try:

  • For reading, use the File.ReadTextAsync and then use the Toml.FromModel string as an input.
  • For writing, you can implement a writer that would delegate to a separate thread and in this thread, you can perform async writes

Thanks for the explanation.

Is this something you'd accept contributions for, or something you'd never accept into Tomlyn? If you'd never accept contributions for, I think you can close this issue.

xoofx commented

Is this something you'd accept contributions for, or something you'd never accept into Tomlyn? If you'd never accept contributions for, I think you can close this issue.

For reading, the parsing system is entirely relying on a string in memory, so it wouldn't be required to add anything. For writing that would require to duplicate the code entirely.

I would like to understand the use case. Why is it that important that you need to have an async version of Tomlyn? Couldn't you serialize to a string in memory and then serialize the string to the disk with async separately. That would be much more efficient in terms of async usage (one write, instead of an async state machine for every single TextWriter.Write)