diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0a696ab..2e0ae89 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
 
 <!-- The line "## <square-bracket>Unreleased</square-bracket>" is replaced by the ci/release.py script with the new release version and release date. -->
 
+## [Unreleased]
+
+### Added
+
+- Added `access_modifiers.disable()` to disable access checks, e.g. in production. This method should be called before any access modifier decorators are compiled, so somewhere at the start of your program. Closes [#3](https://github.com/fniessink/access-modifiers/issues/3). 
+
 ## [0.2.1] - [2019-08-26]
 
 ### Fixed
diff --git a/README.md b/README.md
index e2b4fd9..f0fc54b 100644
--- a/README.md
+++ b/README.md
@@ -70,6 +70,23 @@ print(c.static_private_method())  # Raises an exception
 
 Combining protected methods with static methods is not supported. Combining access modifiers with class methods is not supported (yet).
 
+## Performance
+
+The access modifier decorators work by looking at the code that is calling the decorator to decide whether it is allowed to call the method. To do so, the decorators use implementation details of CPython, like sys._getframe() and the names of code objects such as lambdas and modules. These checks are done on each method call. Consequently, there is a considerable performance impact. Therefore it's recommended to use the access modifiers during testing and turn them off in production using the `access_modifiers.disable()` method. Note that you need to call this method before any of the access modifier decorators are evaluated, i.e.:
+
+```python
+from access_modifiers import disable, privatemethod
+
+disable()  # This will disable the access checks
+
+class Class:
+    @privatemethod
+    def private_method(self) -> str:
+        return "private_method"
+
+disable()  # Calling disable here will not work, Class.private_method has already been wrapped
+```
+
 ## Installation
 
 The package is available from the Python Package Index, install with `pip install access-modifiers`.
@@ -84,8 +101,4 @@ To run the unittests and measure the coverage (which should always be at 100%):
 
 To run Pylint (which should score a 10) and Mypy (which shouldn't complain): `ci/quality.sh`.
 
-## Implementation notes
-
-Both the `privatemethod` and the `protectedmethod` decorator work by looking at the code that is calling the decorator to decide whether it is allowed to call the method. To do so, the decorators use implementation details of CPython, like `sys._getframe()` and the names of code objects such as lambdas and modules. 
-
 The implementation is driven by (unit) tests and has 100% unit test statement and branch coverage. Please look at the tests to see which usage scenario's are currently covered.
diff --git a/access_modifiers/access_modifiers.py b/access_modifiers/access_modifiers.py
index 77ec865..cf99620 100644
--- a/access_modifiers/access_modifiers.py
+++ b/access_modifiers/access_modifiers.py
@@ -12,8 +12,25 @@ class AccessException(Exception):
 ReturnType = TypeVar('ReturnType')
 
 
+_CHECK_ACCESS = True
+
+
+def disable() -> None:
+    """Disable all access checks. Needs to be invoked before the decorators are evaluated."""
+    global _CHECK_ACCESS  # pylint: disable=global-statement
+    _CHECK_ACCESS = False
+
+
+def enable() -> None:
+    """Enable all access checks. For testing purposes."""
+    global _CHECK_ACCESS  # pylint: disable=global-statement
+    _CHECK_ACCESS = True
+
+
 def privatemethod(method: Callable[..., ReturnType]) -> Callable[..., ReturnType]:
     """Decorator that creates a private method."""
+    if not _CHECK_ACCESS:
+        return method
     method_class_qualname = getframe(1).f_locals.get("__qualname__")
     @wraps(method)
     def private_method_wrapper(*args, **kwargs) -> ReturnType:
@@ -40,6 +57,8 @@ def privatemethod(method: Callable[..., ReturnType]) -> Callable[..., ReturnType
 
 def protectedmethod(method: Callable[..., ReturnType]) -> Callable[..., ReturnType]:
     """Decorator that creates a protected method."""
+    if not _CHECK_ACCESS:
+        return method
     @wraps(method)
     def protected_method_wrapper(*args, **kwargs) -> ReturnType:
         """Wrap the original method to make it protected."""

diff --git a/access_modifiers/tests/test_private.py b/access_modifiers/tests/test_private.py
index 97ac772..747d525 100644
--- a/access_modifiers/tests/test_private.py
+++ b/access_modifiers/tests/test_private.py
@@ -2,7 +2,7 @@
 
 import unittest
 
-from ..access_modifiers import AccessException, privatemethod, protectedmethod
+from ..access_modifiers import AccessException, disable, enable, privatemethod, protectedmethod
 
 
 class PrivateMethodTests(unittest.TestCase):
@@ -52,16 +52,29 @@ class PrivateMethodTests(unittest.TestCase):
             return "Subclass.private_method -> " + super().private_method()  # pragma: nocover
 
     def test_call_private_method_directly(self):
-        """Test the accessing a private method throws an exception."""
+        """Test that accessing a private method throws an exception."""
         self.assertRaises(AccessException, self.Class().private_method)
-        self.assertRaises(AccessException, self.Class.private_method, self.Class())
+
+    def test_call_private_method_directly_without_access_checks(self):
+        """Test that accessing a private method without access checks works."""
+        try:
+            disable()
+
+            class Class:
+                @privatemethod
+                def private_method(self):  # pylint: disable=no-self-use
+                    return "Class.private_method"
+
+            self.assertEqual("Class.private_method", Class().private_method())
+        finally:
+            enable()
 
     def test_call_private_method_via_public_method(self):
-        """Test the accessing a private method via a public method is allowed."""
+        """Test that accessing a private method via a public method is allowed."""
         self.assertEqual("Class.public_method -> Class.private_method", self.Class().public_method())
 
     def test_call_private_method_via_public_method_from_subclass(self):
-        """Test the accessing a private method via an overridden public method is allowed."""
+        """Test that accessing a private method via an overridden public method is allowed."""
 
         class Subclass(self.Class):
             def public_method(self):
@@ -80,7 +93,7 @@ class PrivateMethodTests(unittest.TestCase):
         self.assertRaises(AccessException, Subclass().public_method)
 
     def test_call_private_method_via_public_method_in_subclass_using_super(self):
-        """Test the accessing a private method via a public method in a subclass is not allowed,
+        """Test that accessing a private method via a public method in a subclass is not allowed,
         not even when using super()."""
 
         class Subclass(self.Class):
@@ -168,3 +181,18 @@ class StaticPrivateMethodTests(PrivateMethodTests):
         @protectedmethod
         def private_method(self):
             return "Subclass.private_method -> " + super().private_method()  # pragma: nocover
+
+    def test_call_private_method_directly_without_access_checks(self):
+        """Test that accessing a private method without access checks works."""
+        try:
+            disable()
+
+            class Class:  # pylint: disable=too-few-public-methods
+                @staticmethod
+                @privatemethod
+                def private_method():
+                    return "Class.private_method"
+
+            self.assertEqual("Class.private_method", Class().private_method())
+        finally:
+            enable()
diff --git a/access_modifiers/tests/test_protected.py b/access_modifiers/tests/test_protected.py
index 414e06d..2ec5a78 100644
--- a/access_modifiers/tests/test_protected.py
+++ b/access_modifiers/tests/test_protected.py
@@ -2,7 +2,7 @@
 
 import unittest
 
-from ..access_modifiers import AccessException, protectedmethod, privatemethod
+from ..access_modifiers import AccessException, enable, disable, protectedmethod, privatemethod
 
 
 class ProtectedMethodTest(unittest.TestCase):
@@ -21,14 +21,27 @@ class ProtectedMethodTest(unittest.TestCase):
     def test_protected_method(self):
         """Test that accessing a protected method throws an exception."""
         self.assertRaises(AccessException, self.Class().protected_method)
-        self.assertRaises(AccessException, self.Class.protected_method, self.Class())
+
+    def test_call_protected_method_directly_without_access_checks(self):
+        """Test that accessing a protected method without access checks works."""
+        try:
+            disable()
+
+            class Class:  # pylint: disable=too-few-public-methods
+                @protectedmethod
+                def protected_method(self):  # pylint: disable=no-self-use
+                    return "Class.protected_method"
+
+            self.assertEqual("Class.protected_method", Class().protected_method())
+        finally:
+            enable()
 
     def test_call_protected_method_via_public_method(self):
-        """Test the accessing a protected method via a public method is allowed."""
+        """Test that accessing a protected method via a public method is allowed."""
         self.assertEqual("Class.public_method -> Class.protected_method", self.Class().public_method())
 
     def test_call_protected_method_via_protected_method(self):
-        """Test the accessing a protected method via a another protected method is allowed."""
+        """Test that accessing a protected method via a another protected method is allowed."""
 
         class Subclass(self.Class):
             @protectedmethod

Add flag to turn off the access modifiers' checks in production
access_modifiers/tests/test_private.py::PrivateMethodTests::test_call_private_method_directly access_modifiers/tests/test_private.py::PrivateMethodTests::test_call_private_method_directly_without_access_checks access_modifiers/tests/test_private.py::PrivateMethodTests::test_call_private_method_from_try_except_block access_modifiers/tests/test_private.py::PrivateMethodTests::test_call_private_method_via_list_comprehension access_modifiers/tests/test_private.py::PrivateMethodTests::test_call_private_method_via_nested_lambda access_modifiers/tests/test_private.py::PrivateMethodTests::test_call_private_method_via_private_method access_modifiers/tests/test_private.py::PrivateMethodTests::test_call_private_method_via_public_method access_modifiers/tests/test_private.py::PrivateMethodTests::test_call_private_method_via_public_method_from_subclass access_modifiers/tests/test_private.py::PrivateMethodTests::test_call_private_method_via_public_method_in_subclass access_modifiers/tests/test_private.py::PrivateMethodTests::test_call_private_method_via_public_method_in_subclass_using_super access_modifiers/tests/test_private.py::PrivateMethodTests::test_override_private_method access_modifiers/tests/test_private.py::PrivateMethodTests::test_override_private_method_with_protected_method access_modifiers/tests/test_private.py::StaticPrivateMethodTests::test_call_private_method_directly access_modifiers/tests/test_private.py::StaticPrivateMethodTests::test_call_private_method_directly_without_access_checks access_modifiers/tests/test_private.py::StaticPrivateMethodTests::test_call_private_method_from_try_except_block access_modifiers/tests/test_private.py::StaticPrivateMethodTests::test_call_private_method_via_list_comprehension access_modifiers/tests/test_private.py::StaticPrivateMethodTests::test_call_private_method_via_nested_lambda access_modifiers/tests/test_private.py::StaticPrivateMethodTests::test_call_private_method_via_private_method access_modifiers/tests/test_private.py::StaticPrivateMethodTests::test_call_private_method_via_public_method access_modifiers/tests/test_private.py::StaticPrivateMethodTests::test_call_private_method_via_public_method_from_subclass access_modifiers/tests/test_private.py::StaticPrivateMethodTests::test_call_private_method_via_public_method_in_subclass access_modifiers/tests/test_private.py::StaticPrivateMethodTests::test_call_private_method_via_public_method_in_subclass_using_super access_modifiers/tests/test_private.py::StaticPrivateMethodTests::test_override_private_method access_modifiers/tests/test_private.py::StaticPrivateMethodTests::test_override_private_method_with_protected_method access_modifiers/tests/test_protected.py::ProtectedMethodTest::test_call_overridden_protected_method_via_overridden_public_method access_modifiers/tests/test_protected.py::ProtectedMethodTest::test_call_protected_method_directly_without_access_checks access_modifiers/tests/test_protected.py::ProtectedMethodTest::test_call_protected_method_via_overridden_public_method access_modifiers/tests/test_protected.py::ProtectedMethodTest::test_call_protected_method_via_protected_method access_modifiers/tests/test_protected.py::ProtectedMethodTest::test_call_protected_method_via_public_method access_modifiers/tests/test_protected.py::ProtectedMethodTest::test_call_protected_method_via_public_method_in_subclass access_modifiers/tests/test_protected.py::ProtectedMethodTest::test_call_protected_method_via_public_method_using_super access_modifiers/tests/test_protected.py::ProtectedMethodTest::test_override_protected_method_with_private_method access_modifiers/tests/test_protected.py::ProtectedMethodTest::test_override_protected_method_with_protected_method access_modifiers/tests/test_protected.py::ProtectedMethodTest::test_override_protected_method_with_public_method access_modifiers/tests/test_protected.py::ProtectedMethodTest::test_protected_method