chore: Revert "feat: add caching to GapicCallable (#666)" (#744)

This reverts commit 169511959497bd4509305c5424532e817c6a9cb2.
diff --git a/google/api_core/gapic_v1/method.py b/google/api_core/gapic_v1/method.py
index c26342e..0f14ea9 100644
--- a/google/api_core/gapic_v1/method.py
+++ b/google/api_core/gapic_v1/method.py
@@ -42,6 +42,24 @@
 so the default should be used."""
 
 
+def _is_not_none_or_false(value):
+    return value is not None and value is not False
+
+
+def _apply_decorators(func, decorators):
+    """Apply a list of decorators to a given function.
+
+    ``decorators`` may contain items that are ``None`` or ``False`` which will
+    be ignored.
+    """
+    filtered_decorators = filter(_is_not_none_or_false, reversed(decorators))
+
+    for decorator in filtered_decorators:
+        func = decorator(func)
+
+    return func
+
+
 class _GapicCallable(object):
     """Callable that applies retry, timeout, and metadata logic.
 
@@ -73,53 +91,44 @@
     ):
         self._target = target
         self._retry = retry
-        if isinstance(timeout, (int, float)):
-            timeout = TimeToDeadlineTimeout(timeout=timeout)
         self._timeout = timeout
         self._compression = compression
-        self._metadata = list(metadata) if metadata is not None else None
+        self._metadata = metadata
 
     def __call__(
         self, *args, timeout=DEFAULT, retry=DEFAULT, compression=DEFAULT, **kwargs
     ):
         """Invoke the low-level RPC with retry, timeout, compression, and metadata."""
 
+        if retry is DEFAULT:
+            retry = self._retry
+
+        if timeout is DEFAULT:
+            timeout = self._timeout
+
         if compression is DEFAULT:
             compression = self._compression
-        if compression is not None:
-            kwargs["compression"] = compression
+
+        if isinstance(timeout, (int, float)):
+            timeout = TimeToDeadlineTimeout(timeout=timeout)
+
+        # Apply all applicable decorators.
+        wrapped_func = _apply_decorators(self._target, [retry, timeout])
 
         # Add the user agent metadata to the call.
         if self._metadata is not None:
-            try:
-                # attempt to concatenate default metadata with user-provided metadata
-                kwargs["metadata"] = [*kwargs["metadata"], *self._metadata]
-            except (KeyError, TypeError):
-                # if metadata is not provided, use just the default metadata
-                kwargs["metadata"] = self._metadata
+            metadata = kwargs.get("metadata", [])
+            # Due to the nature of invocation, None should be treated the same
+            # as not specified.
+            if metadata is None:
+                metadata = []
+            metadata = list(metadata)
+            metadata.extend(self._metadata)
+            kwargs["metadata"] = metadata
+        if self._compression is not None:
+            kwargs["compression"] = compression
 
-        call = self._build_wrapped_call(timeout, retry)
-        return call(*args, **kwargs)
-
-    @functools.lru_cache(maxsize=4)
-    def _build_wrapped_call(self, timeout, retry):
-        """
-        Build a wrapped callable that applies retry, timeout, and metadata logic.
-        """
-        wrapped_func = self._target
-        if timeout is DEFAULT:
-            timeout = self._timeout
-        elif isinstance(timeout, (int, float)):
-            timeout = TimeToDeadlineTimeout(timeout=timeout)
-        if timeout is not None:
-            wrapped_func = timeout(wrapped_func)
-
-        if retry is DEFAULT:
-            retry = self._retry
-        if retry is not None:
-            wrapped_func = retry(wrapped_func)
-
-        return wrapped_func
+        return wrapped_func(*args, **kwargs)
 
 
 def wrap_method(
@@ -193,9 +202,8 @@
 
     Args:
         func (Callable[Any]): The function to wrap. It should accept an
-            optional ``timeout`` (google.api_core.timeout.Timeout) argument.
-            If ``metadata`` is not ``None``, it should accept a ``metadata``
-            (Sequence[Tuple[str, str]]) argument.
+            optional ``timeout`` argument. If ``metadata`` is not ``None``, it
+            should accept a ``metadata`` argument.
         default_retry (Optional[google.api_core.Retry]): The default retry
             strategy. If ``None``, the method will not retry by default.
         default_timeout (Optional[google.api_core.Timeout]): The default
diff --git a/tests/unit/gapic/test_method.py b/tests/unit/gapic/test_method.py
index 8ada092..87aa639 100644
--- a/tests/unit/gapic/test_method.py
+++ b/tests/unit/gapic/test_method.py
@@ -222,24 +222,3 @@
     with pytest.raises(ValueError) as exc_info:
         google.api_core.gapic_v1.method.wrap_method(method, with_call=True)
     assert "with_call=True is only supported for unary calls" in str(exc_info.value)
-
-
-def test_benchmark_gapic_call():
-    """
-    Ensure the __call__ method performance does not regress from expectations
-
-    __call__ builds a new wrapped function using passed-in timeout and retry, but
-    subsequent calls are cached
-
-    Note: The threshold has been tuned for the CI workers. Test may flake on
-    slower hardware
-    """
-    from google.api_core.gapic_v1.method import _GapicCallable
-    from google.api_core.retry import Retry
-    from timeit import timeit
-
-    gapic_callable = _GapicCallable(
-        lambda *a, **k: 1, retry=Retry(), timeout=1010, compression=False
-    )
-    avg_time = timeit(lambda: gapic_callable(), number=10_000)
-    assert avg_time < 0.4