### Summary

Executing a playbook with many hosts, there is massive overhead in checking whether the hosts list is a pattern, see for yourself on this callgrind graph:

![grafik](https://user-images.githubusercontent.com/3154871/111359016-4a4bf480-868b-11eb-8c8f-55b6a6a10bd7.png)

https://github.com/ansible/ansible/blob/da60525610a384bb04833b1c6429d9db6a87ef64/lib/ansible/vars/manager.py#L490

That check has quadratic runtime with the number of hosts - with a lot of hosts, commenting that check out reduces runtime manyfold.

### Issue Type

Bug Report

### Component Name

variable manager

### Ansible Version

2.10.5, devel

### OS / Environment

Ubuntu

### Steps to Reproduce

```yaml
- hosts: localhost
  tasks:
    - set_fact:
        extra_tasks: true # compute it
        hosts: "{{ [an, array, with, 5100, computed, hosts] }}"

- hosts: "{{ hostvars.localhost.hosts }}"
  vars:
    extra_tasks: "{{ hostvars.localhost.do_extra_tasks }}"
  tasks:
   # some more tasks here
    - name: Execute extra tasks
      command: /bin/true # example
      when: extra_tasks
```

### Expected Results

Execute in tens of seconds.

### Actual Results

Take over 5 minutes to execute.
}
                    worker_prc = WorkerProcess(self._final_q, task_vars, host, task, play_context, self._loader, self._variable_manager, plugin_loader)
                    self._workers[self._cur_worker] = worker_prc
                    self._tqm.send_callback('v2_runner_on_start', host, task)
                    worker_prc.start()
                    display.debug("worker is %d (out of %d available)" % (self._cur_worker + 1, len(self._workers)))
                    queued = True
                self._cur_worker += 1
                if self._cur_worker >= rewind_point:
                    self._cur_worker = 0
                if queued:
                    break
                elif self._cur_worker == starting_worker:
                    time.sleep(0.0001)
            if isinstance(task, Handler):
                self._pending_handler_results += 1
            else:
                self._pending_results += 1
        except (EOFError, IOError, AssertionError) as e:
            
            display.debug("got an error while queuing: %s" % e)
            return
        display.debug("exiting _queue_task() for %s/%s" % (host.name, task.action))
    def get_task_hosts(self, iterator, task_host, task):
        if task.run_once:
            host_list = [host for host in self._hosts_cache if host not in self._tqm._unreachable_hosts]
        else:
            host_list = [task_host.name]
        return host_list
    def get_delegated_hosts(self, result, task):