1

Is AsyncProducerConsumerQueue<byte> (maxCount: 10*1024*204) designed to handle gigabytes of bytes or is there a better way to create a streaming queue for a gigabyte of bytes? Is it better to put byte[] of some size into the queue?

It just sounds weird for me to call await Dequeue a billion times...

D.R.
  • 20,268
  • 21
  • 102
  • 205

1 Answers1

2

AsyncProducerConsumerQueue - like all the other types in AsyncEx - is written for maintainability and correctness, not performance.

For a performant asynchronous queue, I recommend Channels. You do still end up calling await lots of times, but Channels use ValueTask<T> which is very performant especially in the synchronous case.

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
  • 2
    If anybody comes around to read my question and this answer: it was not performant enough to await each single byte from the stream. We ended up putting byte arrays of 4096 bytes each into the channel which worked like a charm. Thanks again for pointing out channels Stephen! – D.R. Feb 18 '20 at 18:25
  • @D.R.: Are you using something pre-.NET Core 3.0? [3.0 got some performance improvements that help Channels be even more efficient than they already were](https://devblogs.microsoft.com/dotnet/performance-improvements-in-net-core-3-0/). – Stephen Cleary Feb 18 '20 at 18:36
  • We're using .NET Framework 4.7.2 + the newest version of the System.Threading.Channels NuGet package. Don't know if they should've those improvements too. – D.R. Feb 19 '20 at 17:04
  • 1
    @D.R.: No, those performance improvements are (and always will be) .NET Core only. – Stephen Cleary Feb 19 '20 at 18:31
  • The performance improvements are very nice indeed, I see ratios of 0.3 to 0.5 in the synthetic benchmarks presented in the blog article. However, that's by far not fast enough to stream a gigabyte byte-by-byte through a channel. We've used a Writer->Channel->Reader->StreamContent->HttpClient->WebService set up to transfer 800MB in around 2min to a localhost web service (the streaming is was to blame). After switching to byte[] of 4096 bytes we're down to 8s (approx. what our loopback gives us at max rates). – D.R. Feb 19 '20 at 19:35