python中频繁的print到底能浪费多长时间

部署运行你感兴趣的模型镜像

python 调试代码的时候,经常在各个地方加入大量的print 来监测每一步的输出,
但是对于大批量数据处理时,print 往往增加几十倍的耗时,严重影响效率。所以最好
养成调试的时候print ,调试完成后,需要核实并注释没有必要的print的习惯。
简单测试一下:

import time
 
a=time.time()
num=0
while num<10000:
    num=num+1
    print(num)
print('有"print"时的耗时:%f' %(time.time()-a))
 
b=time.time()
num=0
while num<10000:
    num=num+1
print('没有"print"时的耗时:%f' %(time.time()-b))


结果:
有"print"时的耗时:0.028803
没有"print"时的耗时:0.001217

使用的是电脑 cpu:i7-9750H   内存:16G

您可能感兴趣的与本文相关的镜像

Python3.10

Python3.10

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

Python 多线程拉取视频流并使用 YOLO 进行目标检测时,长时间运行后出现卡死问题,通常是由以下几个原因导致的: --- ### **1. GIL(全局解释器锁)限制** Python 的多线程在 CPU 密集型任务中受 GIL 限制,无法真正并行执行多个线程。YOLO 推理是典型的 CPU/GPU 密集型操作,多线程并不能提升性能,反而可能因频繁上下文切换导致资源浪费和卡顿。 > **解释**:虽然你用了多线程拉流和处理,但 Python 的 GIL 使得同一时间只有一个线程执行 Python 字节码,因此多线程对计算密集型任务无效。 --- ### **2. 视频流缓冲区堆积(Buffer Accumulation)** 使用 `cv2.VideoCapture` 拉取 RTSP 或网络视频流时,默认会持续缓存帧数据。如果主线程处理速度跟不上采集速度,缓冲区会不断增长,占用大量内存,最终导致延迟、卡顿甚至崩溃。 > **解释**:OpenCV 的 `VideoCapture` 在后台自动预读帧,如果你不及时消费,就会形成“帧堆积”。例如每秒拉30帧,但只处理10帧,剩下的20帧就积压在缓冲区。 --- ### **3. 内存泄漏或资源未释放** - YOLO 模型推理过程中(如使用 `torch` 或 `onnxruntime`),若没有正确管理张量、显存或图像对象,可能导致内存/显存泄漏。 - OpenCV 图像对象未及时释放(尤其是在循环中创建大量 `np.ndarray`)也会造成内存上涨。 --- ### **4. 线程同步问题** 多线程之间共享资源(如队列、图像帧)时,如果没有合理加锁或使用线程安全结构,可能出现死锁、竞争条件等问题,导致程序挂起。 --- ### **5. YOLO 推理耗时过长阻塞主线程** 如果 YOLO 推理放在主线程中同步执行,而模型较大(如 YOLOv5l、YOLOv8m 等),单帧推理时间超过几十毫秒,就会拖慢整体流程,造成视频流采集端积压,进而卡死。 --- ### **6. 显存不足(GPU 版本常见)** 使用 GPU 加速 YOLO 时,若同时处理多个视频流或帧率过高,显存可能耗尽,导致 CUDA out of memory 错误,程序卡住或崩溃。 --- ## ✅ 解决方案与优化建议 ```python import cv2 import threading import time import queue import torch from ultralytics import YOLO # ================ 参数配置 ================ RTSP_URL = "rtsp://your_stream_url" FRAME_QUEUE_SIZE = 5 # 控制最大缓存帧数,防堆积 DET_QUEUE_SIZE = 2 TARGET_FPS = 15 # 控制处理帧率,避免过载 # ================ 共享队列 ================ frame_queue = queue.Queue(maxsize=FRAME_QUEUE_SIZE) det_queue = queue.Queue(maxsize=DET_QUEUE_SIZE) # ================ YOLO 模型加载 ================ model = YOLO('yolov8s.pt') # 推荐使用较小模型加快推理 device = 'cuda' if torch.cuda.is_available() else 'cpu' model.to(device) # ================ 视频采集线程 ================ def video_capture(): cap = cv2.VideoCapture(RTSP_URL) cap.set(cv2.CAP_PROP_BUFFERSIZE, 1) # 关键!限制缓冲区只保留最新1帧 prev_time = time.time() while True: if frame_queue.full(): # 队列满时丢弃最老的一帧,确保只处理最新帧 try: frame_queue.get_nowait() except queue.Empty: pass ret, frame = cap.read() if not ret: print("无法获取帧,重连...") time.sleep(1) cap.release() cap = cv2.VideoCapture(RTSP_URL) continue curr_time = time.time() # 控制采集帧率 if curr_time - prev_time < 1.0 / TARGET_FPS: continue prev_time = curr_time try: frame_queue.put(frame, timeout=1) except queue.Full: pass # 已经做了判断,这里保险 cap.release() # ================ 推理处理线程 ================ def yolo_inference(): while True: try: frame = frame_queue.get(timeout=1) except queue.Empty: continue # 使用 half 精度(GPU)加速推理 results = model(frame, verbose=False) # 可视化结果(可选) annotated_frame = results[0].plot() # 将结果放入显示队列 try: det_queue.put(annotated_frame, block=True, timeout=1) except queue.Full: pass # 跳过旧结果 # 手动释放资源 del results, annotated_frame, frame # ================ 显示线程 ================ def display_results(): while True: try: result_frame = det_queue.get(timeout=1) except queue.Empty: continue cv2.imshow('YOLO Detection', result_frame) if cv2.waitKey(1) == ord('q'): break cv2.destroyAllWindows() # ================ 主函数启动多线程 ================ if __name__ == '__main__': t1 = threading.Thread(target=video_capture, daemon=True) t2 = threading.Thread(target=yolo_inference, daemon=True) t3 = threading.Thread(target=display_results, daemon=True) t1.start() t2.start() t3.start() try: while True: time.sleep(1) except KeyboardInterrupt: print("退出程序") ``` --- ## 🔍 代码关键点说明: 1. **限制 `frame_queue` 大小**:防止帧堆积。 2. **设置 `CAP_PROP_BUFFERSIZE=1`**:OpenCV 不要缓存多余帧。 3. **跳帧机制**:控制采集和处理频率,避免过载。 4. **使用 `.put()` 和 `.get()` 超时机制**:防止线程阻塞。 5. **`daemon=True`**:主线程退出时自动关闭子线程。 6. **及时删除中间变量**:减少内存压力。 --- ## 📌 更进一步优化建议: - 使用 **多进程(multiprocessing)** 替代多线程,绕过 GIL。 - 对每个视频流使用独立进程处理(适合多路摄像头)。 - 使用 TensorRT 加速 YOLO 模型推理。 - 改用异步框架(如 `asyncio` + `aiortc` 或 `uvloop`)处理流媒体。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值