diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4ab44d8c3ce9a261f38f5d308959d3a9ab5bfcb8..a9aa34c9486e8138f9bcb5637dfa7be9a4fc5733 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -4,13 +4,6 @@ project(nbtest VERSION 0.1.0 LANGUAGES C CXX)
 find_package(Python 3.10 COMPONENTS Interpreter Development.Module REQUIRED)
 add_subdirectory(extern/nanobind)
 
-# Find the NumPy include directory
-execute_process(
-  COMMAND "${Python_EXECUTABLE}" -c "import numpy as np; print(np.get_include())"
-  OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE NUMPY_DIR)
-
-message(STATUS "NumPy include directory: ${NUMPY_DIR}")
-
 # Ensure Release build type is set
 if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
   set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
@@ -19,7 +12,6 @@ endif()
 
 # Add the extension module to the build
 nanobind_add_module(my_ext src/my_ext.cc)
-target_include_directories(my_ext PRIVATE ${NUMPY_DIR})
 
 # Copy the built extension to the src directory
 add_custom_command(TARGET my_ext POST_BUILD
diff --git a/src/main.py b/src/main.py
index 71206aa9c6221f0dc0888a6235d289774702374b..eb4bc43bb8670ff5045be52c4e568f4040fe494c 100644
--- a/src/main.py
+++ b/src/main.py
@@ -1,5 +1,5 @@
 # %% Imports
-from my_ext import add, array_sum, array_sum_nocopy, array_sum_pyobj
+from my_ext import add, array_sum, array_sum_nocopy
 import numpy as np
 
 # %% The simple add function
@@ -12,7 +12,6 @@ x = np.random.normal(0, 1, 500)
 x.sum()
 array_sum(x)
 array_sum_nocopy(x)
-array_sum_pyobj(x)
 
 # array_sum works with lists also (smart conversion)
 array_sum([1, 2, 3, 4, 5])
diff --git a/src/my_ext.cc b/src/my_ext.cc
index d2845e9cb2dd7cc154c10cd73ea9a93ab14de2a5..8f8cd896072e99f03d7b89da09b70315b91f1fad 100644
--- a/src/my_ext.cc
+++ b/src/my_ext.cc
@@ -1,9 +1,3 @@
-extern "C" {
-#include <Python.h>
-#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
-#include <numpy/ndarrayobject.h>
-}
-
 #include <nanobind/nanobind.h>
 #include <nanobind/ndarray.h>
 #include <nanobind/stl/vector.h>
@@ -12,17 +6,6 @@ extern "C" {
 
 namespace nb = nanobind;
 
-double
-array_sum_pyobj(const nb::object &o)
-{
-    // This is an unsafe solution ... but fast
-    auto *a = reinterpret_cast<PyArrayObject *>(o.ptr());  // Now numpy array object
-    const auto p = static_cast<double *>(PyArray_DATA(a)); // Pointer to data
-    const auto sizes = PyArray_SHAPE(a);                   // Sizes of each dimension
-
-    return std::accumulate(p, p + sizes[0], 0.0);
-}
-
 int
 add(int a, int b)
 {
@@ -47,5 +30,4 @@ NB_MODULE(my_ext, m)
     m.def("add", &add);
     m.def("array_sum", &array_sum);
     m.def("array_sum_nocopy", &array_sum_nocopy);
-    m.def("array_sum_pyobj", &array_sum_pyobj);
 }
diff --git a/src/timing_profile.py b/src/timing_profile.py
deleted file mode 100644
index 4dff4b14f88f3dd66c854c98788af49ba674a225..0000000000000000000000000000000000000000
--- a/src/timing_profile.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# %%
-import timeit
-from my_ext import array_sum, array_sum_nocopy, array_sum_pyobj  # noqa
-import numpy as np
-import matplotlib.pyplot as plt
-from seaborn import despine
-
-
-# %% Utils
-def bs_mean_ci(x, alpha=0.95, n_bootstrap=1000):
-    """Bootstrap mean and confidence interval."""
-    n, _ = x.shape
-    mu = np.zeros(n)
-    ci = np.zeros((n, 2))
-    for k, xi in enumerate(x):
-        bs = np.random.choice(xi, size=(n_bootstrap,), replace=True)
-        mu[k] = bs.mean()
-        ci[k] = np.percentile(bs, [(1 - alpha) * 100 / 2, 100 - (1 - alpha) * 100 / 2])
-    return mu, ci
-
-
-# %% Perform timing experiments
-R = 20  # Number of repeated timing experiments
-M = 500  # Number of iterations in each timing measurement
-N = np.logspace(1, 5, 10).astype(int)  # Sizes to test
-
-res = {"np": [], "array_sum": [], "array_sum_nocopy": [], "array_sum_pyobj": []}
-for Ni in N:
-    print(f"Ni = {Ni}")
-    x = np.random.normal(0, 1, int(Ni))
-    ri = np.array(timeit.repeat("x.sum()", globals=globals(), number=M, repeat=R)) / M
-    res["np"].append(ri)
-
-    ri = np.array(timeit.repeat("array_sum(x)", globals=globals(), number=M, repeat=R)) / M
-    res["array_sum"].append(ri)
-
-    ri = np.array(timeit.repeat("array_sum_nocopy(x)", globals=globals(), number=M, repeat=R)) / M
-    res["array_sum_nocopy"].append(ri)
-
-    ri = np.array(timeit.repeat("array_sum_pyobj(x)", globals=globals(), number=M, repeat=R)) / M
-    res["array_sum_pyobj"].append(ri)
-
-for k in res:
-    res[k] = np.array(res[k])
-
-
-# %% Plot results
-fig, ax = plt.subplots(num=10, clear=True)
-for k in res:
-    mu, ci = bs_mean_ci(res[k])
-    ax.loglog(N, mu * 1e9, label=k)
-    ax.fill_between(N, ci[:, 0] * 1e9, ci[:, 1] * 1e9, alpha=0.2)
-ax.legend(frameon=False)
-ax.set_xlabel("N")
-ax.set_ylabel("Time (ns)")
-despine(ax=ax)
-
-# %%
-plt.show()