Complete guide to Python's time.thread_time function covering thread-specific CPU time measurement and practical examples.
Last modified April 11, 2025
This comprehensive guide explores Python’s time.thread_time function, which returns the current thread’s CPU time. We’ll cover thread-specific timing, performance measurement, and practical examples.
The time.thread_time function returns the current thread’s CPU time as a float in seconds. It measures time spent executing in the current thread.
Key characteristics: thread-specific CPU time, excludes sleep time, useful for profiling. The reference point is undefined, so only differences are meaningful.
This example shows basic usage of thread_time to measure CPU time consumed by the current thread during a computation.
basic_thread_time.py
import time
def compute(): sum(range(10**6)) # CPU-intensive work
start = time.thread_time() compute() end = time.thread_time()
print(f"CPU time used: {end - start:.6f} seconds")
This measures only the CPU time spent in the current thread. Sleep time or other threads’ work won’t affect the measurement.
The precision depends on the platform but is typically nanosecond-level. Only time differences should be compared.
This example compares thread_time with process_time to show thread-specific vs process-wide CPU time measurement.
thread_vs_process.py
import time import threading
def worker(): start_thread = time.thread_time() start_process = time.process_time()
sum(range(10**7)) # CPU work
end_thread = time.thread_time()
end_process = time.process_time()
print(f"Thread CPU: {end_thread - start_thread:.3f}s")
print(f"Process CPU: {end_process - start_process:.3f}s")
t1 = threading.Thread(target=worker) t2 = threading.Thread(target=worker) t1.start() t2.start() t1.join() t2.join()
thread_time measures only the calling thread’s CPU time, while process_time includes all threads in the process.
This distinction is crucial when profiling multi-threaded applications.
This example demonstrates how thread_time distinguishes between CPU-bound and I/O-bound operations in a thread.
io_vs_cpu.py
import time
def mixed_work(): # CPU-bound work start_cpu = time.thread_time() sum(range(10**6)) end_cpu = time.thread_time()
# I/O-bound work (sleep simulates waiting)
start_io = time.thread_time()
time.sleep(1)
end_io = time.thread_time()
print(f"CPU work time: {end_cpu - start_cpu:.6f}s")
print(f"I/O wait time: {end_io - start_io:.6f}s")
mixed_work()
Sleep time doesn’t count toward thread CPU time, showing how thread_time only measures actual CPU usage.
This helps identify whether a thread is CPU-bound or waiting on I/O operations.
This example creates a decorator that profiles functions using thread_time to measure their CPU consumption.
profiler.py
import time
def profile(func): def wrapper(*args, **kwargs): start = time.thread_time() result = func(*args, **kwargs) end = time.thread_time() print(f"{func.name} used {end - start:.6f}s CPU time") return result return wrapper
@profile def factorial(n): if n == 0: return 1 return n * factorial(n - 1)
@profile def sleep_and_compute(): time.sleep(0.5) sum(range(10**6))
factorial(10) sleep_and_compute()
The decorator measures only the CPU time used by the function, excluding any time spent waiting or in other threads.
This is particularly useful for identifying CPU-intensive functions in multi-threaded applications.
This example uses thread_time to compare the CPU consumption of different thread implementations of the same task.
thread_comparison.py
import time import threading
def worker_optimized(): start = time.thread_time() # Efficient computation sum(i*i for i in range(10**6)) end = time.thread_time() print(f"Optimized: {end - start:.6f}s")
def worker_unoptimized(): start = time.thread_time() # Less efficient computation total = 0 for i in range(10**6): total += i*i end = time.thread_time() print(f"Unoptimized: {end - start:.6f}s")
t1 = threading.Thread(target=worker_optimized) t2 = threading.Thread(target=worker_unoptimized) t1.start() t2.start() t1.join() t2.join()
By measuring each thread’s CPU time separately, we can compare the efficiency of different implementations running concurrently.
This approach helps identify performance optimizations in multi-threaded code.
This example shows how to monitor a thread’s CPU usage over time using thread_time with periodic sampling.
monitoring.py
import time import threading
def worker(): last_time = time.thread_time() for i in range(5): # Do some work sum(range(10**6))
current_time = time.thread_time()
cpu_used = current_time - last_time
print(f"Interval {i}: {cpu_used:.3f}s CPU time")
last_time = current_time
# Simulate mixed workload
time.sleep(0.2)
thread = threading.Thread(target=worker) thread.start() thread.join()
By taking periodic measurements, we can track how CPU usage varies during a thread’s execution.
This technique is useful for identifying phases of high CPU usage in long-running threads.
Thread-specific: Use for measuring single thread CPU time only
Relative measurements: Only differences between calls are meaningful
Precision: Provides high-resolution timing for profiling
Sleep time: Excludes time when thread is not running
Multi-threading: Ideal for profiling concurrent applications
My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.
List all Python tutorials.