1

Our codebase has around 800 functions that return AnyPublisher<Type, Error>, since I'd like to use language-specific features I cannot find any resource or reference that compares performance or drawbacks of using any Publisher or some Publisher as replacement.

Is there any efficient way to test it myself eventually?

Dávid Pásztor
  • 51,403
  • 9
  • 85
  • 116
Mattia C.
  • 700
  • 1
  • 5
  • 15
  • 3
    Did you even try replacing some of them with `any Publisher` and `some Publisher`? If you did, you would have found out that *this generally doesn't work*. You can't use many of the publisher operators on `any Publisher`, and replacing with `some Publisher` isn't always an option, when your function can return multiple types of publishers for example. You are kind of comparing apples and oranges here. – Sweeper Mar 15 '23 at 11:58
  • 2
    "Is there any efficient way to test it myself eventually?" How about using Instruments.app? – Sweeper Mar 15 '23 at 12:01
  • 1
    You have two questions. One is answered by https://stackoverflow.com/questions/61553264/is-there-a-way-to-avoid-using-anypublisher-erasetoanypublisher-all-over-the-plac. The other is "do opaque types come with a performance drawback." No, they don't. So replace all of them when that compiles. But then, audit to see which of them can be replaced by `AsyncSequence`. –  Mar 15 '23 at 12:33
  • 2
    `AnyPublisher` isn't just a convenience to satisfy the type system, type erasing a `Publisher` has the added benefit that the caller cannot access the original type. This can be useful in situations such as when you are using a `Subject`, but only want to be able to publish values through the `Subject` from a limited scope. If you type erase the `Subject` to an `AnyPublisher`, no one will be able to get a `Subject` back, since the type information was erased. However, when using` some Publisher` that is not the case, that can be downcast to a `Subject`. – Dávid Pásztor Mar 15 '23 at 14:04
  • @Sweeper Good assumptions but I tried replacing and `any Publisher` indeed doesn't usually cover my cases while `some Publisher` does, that's why I created this question. – Mattia C. Mar 15 '23 at 15:37

1 Answers1

0

With any performance question the best rule of thumb is "Try it with the profiler to be sure". If you suspect a performance issue then run some tests in Instruments.

Answering your question in general is difficult without a deep investgation into how Apple has implemented any Publisher and AnyPublisher. In my experience this kind of type erasure involves, abstractly speaking, taking a fully typed entity and putting in a "box", that is, wrapping it up inside a level of indirection.

Any code that wants to access the thing inside the box has to go through that level of indirection. This extra level will probably have a (small) cost in terms of absolute performance in both call time and memory.

In contrast, using some Publisher would most commonly happen when you have a generic function: func doSomething<T: somePublisher>(firstArg: T). In this case the compiler will generate a specific version of doSomething for each type. I would expect there to be no extra level of indirection so call time should not be affected. But your code will be larger.

The most "efficient" way for you to test it yourself will be to use the broilers in Instruments. You are bound to run into trade-offs between memory-size and runtime speed... it's a classic computer science problem.

And for what it's worth, Apple themselves have warned against the potential performance penalties of using existentials (i.e. any <Protocol>). Their advice is the same you're getting here though - if you're concerned about it, use the profiler.

Scott Thompson
  • 22,629
  • 4
  • 32
  • 34