Skip to content

Sending to full Channel<Unit>(CONFLATED) is ~10x slower than sending to full Channel<Unit>(1) #4048

Open
@ShikaSD

Description

@ShikaSD

Channel<Unit>(CONFLATED) is a pattern frequently used for signalling in coroutine-based environment. In cases when the channel already contains an element (e.g. receiver is delayed), calling send causes Channel to drop the previous element and replace it with the old one. This behavior is expected and matches documentation of Channel.CONFLATED, but is significantly slower than Channel<Unit>(1), which preserves the original object instead. In cases when the channel can only send/receive the same object (Unit === Unit), the default CONFLATED behavior could be optimized to be more efficient.

Running the benchmarks on Pixel 5:

        // make sure we measure sending to already full channel
        channel.trySend(Unit)

        benchmarkRule.measureRepeated {
            channel.trySend(Unit)
        }

Produces the following results:

         // Executed on Pixel 5 (Android 13)
          652   ns           ChannelBenchmark.conflatedChannelSend
           70.8 ns           ChannelBenchmark.normalChannelSend
          559   ns           ChannelBenchmark.conflatedChannelSend_empty
          576   ns           ChannelBenchmark.normalChannelSend_empty

From the results above, sending to empty channel is roughly the same for both Channel(CONFLATED) and Channel(1), but sending to already full channel is ~10x slower.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions