As Martin mentioned, by default most JMS implementations will process message selectors on the client, unless they are part of a durable subscription, when most JMS implementations will process them on the server as well to avoid too many messages getting persisted when there's a significant reduction in the number of messages that get past the selector. Some systems (like SonicMQ) allow you to specify that message selectors should be processed on the server, which is a good option in a case where you have excess CPU available on your message brokers but not on your consumers.
Bear in mind that while topic-based selection is usually faster, it can be quite cumbersome, because if you want to listen to 5 different things, you have to have 5 different MessageConsumers. Each of those in a naive driver implementation is a different thread, and that can start to add up. For that reason, it is often useful to support both from publication so that some clients can listen only to the topics that they want, and others can listen to the topic hierarchies they want (e.g. foo.#) with message selectors (or code-based selectors).
However, you should always test against your application and your broker. Every broker handles the situation differently, and every application functions differently. You can't just say "always use technique X" because each technique for client-directed message processing has different tradeoffs. Benchmark, benchmark, benchmark.
One thing to bear in mind with message selectors is that they aren't dynamically changeable, so you have the possibility of losing messages or having to manually manage a complicated switchover scenario. Imagine the following use case:
- You are listening to a message selector of the form (Ticker in ('CSCO', 'MSFT'))
- User wants to start listening to AAPL
- You have to shut down the old MessageConsumer and start a new one with a selector in the form (Ticker in ('CSCO, 'MSFT', 'AAPL'))
- During the switchover, you either lose messages (because you shut down the old one before starting the new one) or you have to manually remove duplicates (because you have the new one started before the old one)