From 2b2ab124be4ffa44b805267e65b01b8cd1e28f6d Mon Sep 17 00:00:00 2001 From: SnowindMe <1945743455@qq.com> Date: Sat, 12 Apr 2025 20:50:36 +0800 Subject: [PATCH 01/14] =?UTF-8?q?=E6=9B=B4=E5=A5=BD=E7=9A=84=E8=AE=A1?= =?UTF-8?q?=E6=97=B6=E5=99=A8=E5=B0=8F=E5=B7=A5=E5=85=B7=EF=BC=8C=E6=84=9F?= =?UTF-8?q?=E8=B0=A2D=E6=8C=87=E5=AF=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../reasoning_chat/reasoning_chat.py | 41 ++--- .../reasoning_chat/reasoning_generator.py | 40 ++--- .../think_flow_chat/think_flow_chat.py | 97 +++++------ .../think_flow_chat/think_flow_generator.py | 154 +++++++++--------- src/plugins/utils/timer_calculater.py | 58 +++++++ 5 files changed, 205 insertions(+), 185 deletions(-) create mode 100644 src/plugins/utils/timer_calculater.py diff --git a/src/plugins/chat_module/reasoning_chat/reasoning_chat.py b/src/plugins/chat_module/reasoning_chat/reasoning_chat.py index eea1cc8b8..2ce218a6f 100644 --- a/src/plugins/chat_module/reasoning_chat/reasoning_chat.py +++ b/src/plugins/chat_module/reasoning_chat/reasoning_chat.py @@ -19,6 +19,7 @@ from ...chat.chat_stream import chat_manager from ...person_info.relationship_manager import relationship_manager from ...chat.message_buffer import message_buffer from src.plugins.respon_info_catcher.info_catcher import info_catcher_manager +from ...utils.timer_calculater import Timer # 定义日志配置 chat_config = LogConfig( @@ -173,12 +174,10 @@ class ReasoningChat: await self.storage.store_message(message, chat) # 记忆激活 - timer1 = time.time() - interested_rate = await HippocampusManager.get_instance().get_activate_from_text( - message.processed_plain_text, fast_retrieval=True - ) - timer2 = time.time() - timing_results["记忆激活"] = timer2 - timer1 + with Timer("记忆激活", timing_results): + interested_rate = await HippocampusManager.get_instance().get_activate_from_text( + message.processed_plain_text, fast_retrieval=True + ) # 查询缓冲器结果,会整合前面跳过的消息,改变processed_plain_text buffer_result = await message_buffer.query_buffer_result(message) @@ -228,10 +227,8 @@ class ReasoningChat: await willing_manager.before_generate_reply_handle(message.message_info.message_id) # 创建思考消息 - timer1 = time.time() - thinking_id = await self._create_thinking_message(message, chat, userinfo, messageinfo) - timer2 = time.time() - timing_results["创建思考消息"] = timer2 - timer1 + with Timer("创建思考消息", timing_results): + thinking_id = await self._create_thinking_message(message, chat, userinfo, messageinfo) logger.debug(f"创建捕捉器,thinking_id:{thinking_id}") @@ -239,11 +236,9 @@ class ReasoningChat: info_catcher.catch_decide_to_response(message) # 生成回复 - timer1 = time.time() try: - response_set = await self.gpt.generate_response(message, thinking_id) - timer2 = time.time() - timing_results["生成回复"] = timer2 - timer1 + with Timer("生成回复", timing_results): + response_set = await self.gpt.generate_response(message, thinking_id) info_catcher.catch_after_generate_response(timing_results["生成回复"]) except Exception as e: @@ -255,26 +250,20 @@ class ReasoningChat: return # 发送消息 - timer1 = time.time() - first_bot_msg = await self._send_response_messages(message, chat, response_set, thinking_id) - timer2 = time.time() - timing_results["发送消息"] = timer2 - timer1 + with Timer("发送消息", timing_results): + first_bot_msg = await self._send_response_messages(message, chat, response_set, thinking_id) info_catcher.catch_after_response(timing_results["发送消息"], response_set, first_bot_msg) info_catcher.done_catch() # 处理表情包 - timer1 = time.time() - await self._handle_emoji(message, chat, response_set) - timer2 = time.time() - timing_results["处理表情包"] = timer2 - timer1 + with Timer("处理表情包", timing_results): + await self._handle_emoji(message, chat, response_set) # 更新关系情绪 - timer1 = time.time() - await self._update_relationship(message, response_set) - timer2 = time.time() - timing_results["更新关系情绪"] = timer2 - timer1 + with Timer("更新关系情绪", timing_results): + await self._update_relationship(message, response_set) # 回复后处理 await willing_manager.after_generate_reply_handle(message.message_info.message_id) diff --git a/src/plugins/chat_module/reasoning_chat/reasoning_generator.py b/src/plugins/chat_module/reasoning_chat/reasoning_generator.py index 8b81ca4b2..25416a1d5 100644 --- a/src/plugins/chat_module/reasoning_chat/reasoning_generator.py +++ b/src/plugins/chat_module/reasoning_chat/reasoning_generator.py @@ -7,6 +7,7 @@ from ...config.config import global_config from ...chat.message import MessageThinking from .reasoning_prompt_builder import prompt_builder from ...chat.utils import process_llm_response +from ...utils.timer_calculater import Timer from src.common.logger import get_module_logger, LogConfig, LLM_STYLE_CONFIG from src.plugins.respon_info_catcher.info_catcher import info_catcher_manager @@ -38,7 +39,7 @@ class ResponseGenerator: self.current_model_type = "r1" # 默认使用 R1 self.current_model_name = "unknown model" - async def generate_response(self, message: MessageThinking,thinking_id:str) -> Optional[Union[str, List[str]]]: + async def generate_response(self, message: MessageThinking, thinking_id: str) -> Optional[Union[str, List[str]]]: """根据当前模型类型选择对应的生成函数""" # 从global_config中获取模型概率值并选择模型 if random.random() < global_config.MODEL_R1_PROBABILITY: @@ -52,7 +53,7 @@ class ResponseGenerator: f"{self.current_model_type}思考:{message.processed_plain_text[:30] + '...' if len(message.processed_plain_text) > 30 else message.processed_plain_text}" ) # noqa: E501 - model_response = await self._generate_response_with_model(message, current_model,thinking_id) + model_response = await self._generate_response_with_model(message, current_model, thinking_id) # print(f"raw_content: {model_response}") @@ -65,11 +66,11 @@ class ResponseGenerator: logger.info(f"{self.current_model_type}思考,失败") return None - async def _generate_response_with_model(self, message: MessageThinking, model: LLM_request,thinking_id:str): + async def _generate_response_with_model(self, message: MessageThinking, model: LLM_request, thinking_id: str): sender_name = "" - + info_catcher = info_catcher_manager.get_info_catcher(thinking_id) - + if message.chat_stream.user_info.user_cardname and message.chat_stream.user_info.user_nickname: sender_name = ( f"[({message.chat_stream.user_info.user_id}){message.chat_stream.user_info.user_nickname}]" @@ -82,26 +83,22 @@ class ResponseGenerator: logger.debug("开始使用生成回复-2") # 构建prompt - timer1 = time.time() - prompt = await prompt_builder._build_prompt( - message.chat_stream, - message_txt=message.processed_plain_text, - sender_name=sender_name, - stream_id=message.chat_stream.stream_id, - ) - timer2 = time.time() - logger.info(f"构建prompt时间: {timer2 - timer1}秒") + with Timer() as t_build_prompt: + prompt = await prompt_builder._build_prompt( + message.chat_stream, + message_txt=message.processed_plain_text, + sender_name=sender_name, + stream_id=message.chat_stream.stream_id, + ) + logger.info(f"构建prompt时间: {t_build_prompt.human_readable()}") try: content, reasoning_content, self.current_model_name = await model.generate_response(prompt) - + info_catcher.catch_after_llm_generated( - prompt=prompt, - response=content, - reasoning_content=reasoning_content, - model_name=self.current_model_name) - - + prompt=prompt, response=content, reasoning_content=reasoning_content, model_name=self.current_model_name + ) + except Exception: logger.exception("生成回复时出错") return None @@ -118,7 +115,6 @@ class ResponseGenerator: return content - # def _save_to_db( # self, # message: MessageRecv, diff --git a/src/plugins/chat_module/think_flow_chat/think_flow_chat.py b/src/plugins/chat_module/think_flow_chat/think_flow_chat.py index 964aca55c..098ee1552 100644 --- a/src/plugins/chat_module/think_flow_chat/think_flow_chat.py +++ b/src/plugins/chat_module/think_flow_chat/think_flow_chat.py @@ -20,6 +20,7 @@ from ...chat.chat_stream import chat_manager from ...person_info.relationship_manager import relationship_manager from ...chat.message_buffer import message_buffer from src.plugins.respon_info_catcher.info_catcher import info_catcher_manager +from ...utils.timer_calculater import Timer # 定义日志配置 chat_config = LogConfig( @@ -59,11 +60,7 @@ class ThinkFlowChat: return thinking_id - async def _send_response_messages(self, - message, - chat, - response_set:List[str], - thinking_id) -> MessageSending: + async def _send_response_messages(self, message, chat, response_set: List[str], thinking_id) -> MessageSending: """发送回复消息""" container = message_manager.get_container(chat.stream_id) thinking_message = None @@ -200,12 +197,10 @@ class ThinkFlowChat: logger.debug(f"存储成功{message.processed_plain_text}") # 记忆激活 - timer1 = time.time() - interested_rate = await HippocampusManager.get_instance().get_activate_from_text( - message.processed_plain_text, fast_retrieval=True - ) - timer2 = time.time() - timing_results["记忆激活"] = timer2 - timer1 + with Timer("记忆激活", timing_results): + interested_rate = await HippocampusManager.get_instance().get_activate_from_text( + message.processed_plain_text, fast_retrieval=True + ) logger.debug(f"记忆激活: {interested_rate}") # 查询缓冲器结果,会整合前面跳过的消息,改变processed_plain_text @@ -260,103 +255,85 @@ class ThinkFlowChat: if random() < reply_probability: try: do_reply = True - - # 回复前处理 await willing_manager.before_generate_reply_handle(message.message_info.message_id) # 创建思考消息 try: - timer1 = time.time() - thinking_id = await self._create_thinking_message(message, chat, userinfo, messageinfo) - timer2 = time.time() - timing_results["创建思考消息"] = timer2 - timer1 + with Timer("创建思考消息", timing_results): + thinking_id = await self._create_thinking_message(message, chat, userinfo, messageinfo) except Exception as e: logger.error(f"心流创建思考消息失败: {e}") - + logger.debug(f"创建捕捉器,thinking_id:{thinking_id}") - + info_catcher = info_catcher_manager.get_info_catcher(thinking_id) info_catcher.catch_decide_to_response(message) try: # 观察 - timer1 = time.time() - await heartflow.get_subheartflow(chat.stream_id).do_observe() - timer2 = time.time() - timing_results["观察"] = timer2 - timer1 + with Timer("观察", timing_results): + await heartflow.get_subheartflow(chat.stream_id).do_observe() except Exception as e: logger.error(f"心流观察失败: {e}") - + info_catcher.catch_after_observe(timing_results["观察"]) # 思考前脑内状态 try: - timer1 = time.time() - current_mind,past_mind = await heartflow.get_subheartflow(chat.stream_id).do_thinking_before_reply( - message_txt = message.processed_plain_text, - sender_name = message.message_info.user_info.user_nickname, - chat_stream = chat - ) - timer2 = time.time() - timing_results["思考前脑内状态"] = timer2 - timer1 + with Timer("思考前脑内状态", timing_results): + current_mind, past_mind = await heartflow.get_subheartflow( + chat.stream_id + ).do_thinking_before_reply( + message_txt=message.processed_plain_text, + sender_name=message.message_info.user_info.user_nickname, + chat_stream=chat, + ) except Exception as e: logger.error(f"心流思考前脑内状态失败: {e}") - - info_catcher.catch_afer_shf_step(timing_results["思考前脑内状态"],past_mind,current_mind) + + info_catcher.catch_afer_shf_step(timing_results["思考前脑内状态"], past_mind, current_mind) # 生成回复 - timer1 = time.time() - response_set = await self.gpt.generate_response(message,thinking_id) - timer2 = time.time() - timing_results["生成回复"] = timer2 - timer1 + with Timer("生成回复", timing_results): + response_set = await self.gpt.generate_response(message, thinking_id) info_catcher.catch_after_generate_response(timing_results["生成回复"]) - + if not response_set: logger.info("回复生成失败,返回为空") return # 发送消息 try: - timer1 = time.time() - first_bot_msg = await self._send_response_messages(message, chat, response_set, thinking_id) - timer2 = time.time() - timing_results["发送消息"] = timer2 - timer1 + with Timer("发送消息", timing_results): + first_bot_msg = await self._send_response_messages(message, chat, response_set, thinking_id) except Exception as e: logger.error(f"心流发送消息失败: {e}") - - - info_catcher.catch_after_response(timing_results["发送消息"],response_set,first_bot_msg) - - + + info_catcher.catch_after_response(timing_results["发送消息"], response_set, first_bot_msg) + info_catcher.done_catch() # 处理表情包 try: - timer1 = time.time() - await self._handle_emoji(message, chat, response_set) - timer2 = time.time() - timing_results["处理表情包"] = timer2 - timer1 + with Timer("处理表情包", timing_results): + await self._handle_emoji(message, chat, response_set) except Exception as e: logger.error(f"心流处理表情包失败: {e}") # 更新心流 try: - timer1 = time.time() - await self._update_using_response(message, response_set) - timer2 = time.time() - timing_results["更新心流"] = timer2 - timer1 + with Timer("更新心流", timing_results): + await self._update_using_response(message, response_set) except Exception as e: logger.error(f"心流更新失败: {e}") # 更新关系情绪 try: - timer1 = time.time() - await self._update_relationship(message, response_set) - timer2 = time.time() - timing_results["更新关系情绪"] = timer2 - timer1 + with Timer("更新关系情绪", timing_results): + await self._update_relationship(message, response_set) except Exception as e: logger.error(f"心流更新关系情绪失败: {e}") diff --git a/src/plugins/chat_module/think_flow_chat/think_flow_generator.py b/src/plugins/chat_module/think_flow_chat/think_flow_generator.py index 164e8ab7c..b682a4c5b 100644 --- a/src/plugins/chat_module/think_flow_chat/think_flow_generator.py +++ b/src/plugins/chat_module/think_flow_chat/think_flow_generator.py @@ -1,4 +1,3 @@ -import time from typing import List, Optional import random @@ -10,6 +9,7 @@ from .think_flow_prompt_builder import prompt_builder from ...chat.utils import process_llm_response from src.common.logger import get_module_logger, LogConfig, LLM_STYLE_CONFIG from src.plugins.respon_info_catcher.info_catcher import info_catcher_manager +from ...utils.timer_calculater import Timer from src.plugins.moods.moods import MoodManager @@ -35,44 +35,50 @@ class ResponseGenerator: self.current_model_type = "r1" # 默认使用 R1 self.current_model_name = "unknown model" - async def generate_response(self, message: MessageRecv,thinking_id:str) -> Optional[List[str]]: + async def generate_response(self, message: MessageRecv, thinking_id: str) -> Optional[List[str]]: """根据当前模型类型选择对应的生成函数""" - logger.info( f"思考:{message.processed_plain_text[:30] + '...' if len(message.processed_plain_text) > 30 else message.processed_plain_text}" ) - - arousal_multiplier = MoodManager.get_instance().get_arousal_multiplier() - - time1 = time.time() - - checked = False - if random.random() > 0: - checked = False - current_model = self.model_normal - current_model.temperature = 0.3 * arousal_multiplier #激活度越高,温度越高 - model_response = await self._generate_response_with_model(message, current_model,thinking_id,mode="normal") - - model_checked_response = model_response - else: - checked = True - current_model = self.model_normal - current_model.temperature = 0.3 * arousal_multiplier #激活度越高,温度越高 - print(f"生成{message.processed_plain_text}回复温度是:{current_model.temperature}") - model_response = await self._generate_response_with_model(message, current_model,thinking_id,mode="simple") - - current_model.temperature = 0.3 - model_checked_response = await self._check_response_with_model(message, model_response, current_model,thinking_id) - time2 = time.time() + arousal_multiplier = MoodManager.get_instance().get_arousal_multiplier() + + with Timer() as t_generate_response: + checked = False + if random.random() > 0: + checked = False + current_model = self.model_normal + current_model.temperature = 0.3 * arousal_multiplier # 激活度越高,温度越高 + model_response = await self._generate_response_with_model( + message, current_model, thinking_id, mode="normal" + ) + + model_checked_response = model_response + else: + checked = True + current_model = self.model_normal + current_model.temperature = 0.3 * arousal_multiplier # 激活度越高,温度越高 + print(f"生成{message.processed_plain_text}回复温度是:{current_model.temperature}") + model_response = await self._generate_response_with_model( + message, current_model, thinking_id, mode="simple" + ) + + current_model.temperature = 0.3 + model_checked_response = await self._check_response_with_model( + message, model_response, current_model, thinking_id + ) if model_response: if checked: - logger.info(f"{global_config.BOT_NICKNAME}的回复是:{model_response},思忖后,回复是:{model_checked_response},生成回复时间: {time2 - time1}秒") + logger.info( + f"{global_config.BOT_NICKNAME}的回复是:{model_response},思忖后,回复是:{model_checked_response},生成回复时间: {t_generate_response.human_readable()}" + ) else: - logger.info(f"{global_config.BOT_NICKNAME}的回复是:{model_response},生成回复时间: {time2 - time1}秒") - + logger.info( + f"{global_config.BOT_NICKNAME}的回复是:{model_response},生成回复时间: {t_generate_response.human_readable()}" + ) + model_processed_response = await self._process_response(model_checked_response) return model_processed_response @@ -80,11 +86,13 @@ class ResponseGenerator: logger.info(f"{self.current_model_type}思考,失败") return None - async def _generate_response_with_model(self, message: MessageRecv, model: LLM_request,thinking_id:str,mode:str = "normal") -> str: + async def _generate_response_with_model( + self, message: MessageRecv, model: LLM_request, thinking_id: str, mode: str = "normal" + ) -> str: sender_name = "" - + info_catcher = info_catcher_manager.get_info_catcher(thinking_id) - + if message.chat_stream.user_info.user_cardname and message.chat_stream.user_info.user_nickname: sender_name = ( f"[({message.chat_stream.user_info.user_id}){message.chat_stream.user_info.user_nickname}]" @@ -96,45 +104,41 @@ class ResponseGenerator: sender_name = f"用户({message.chat_stream.user_info.user_id})" # 构建prompt - timer1 = time.time() - if mode == "normal": - prompt = await prompt_builder._build_prompt( - message.chat_stream, - message_txt=message.processed_plain_text, - sender_name=sender_name, - stream_id=message.chat_stream.stream_id, - ) - elif mode == "simple": - prompt = await prompt_builder._build_prompt_simple( - message.chat_stream, - message_txt=message.processed_plain_text, - sender_name=sender_name, - stream_id=message.chat_stream.stream_id, - ) - timer2 = time.time() - logger.info(f"构建{mode}prompt时间: {timer2 - timer1}秒") + with Timer() as t_build_prompt: + if mode == "normal": + prompt = await prompt_builder._build_prompt( + message.chat_stream, + message_txt=message.processed_plain_text, + sender_name=sender_name, + stream_id=message.chat_stream.stream_id, + ) + elif mode == "simple": + prompt = await prompt_builder._build_prompt_simple( + message.chat_stream, + message_txt=message.processed_plain_text, + sender_name=sender_name, + stream_id=message.chat_stream.stream_id, + ) + logger.info(f"构建{mode}prompt时间: {t_build_prompt.human_readable()}") try: content, reasoning_content, self.current_model_name = await model.generate_response(prompt) - - + info_catcher.catch_after_llm_generated( - prompt=prompt, - response=content, - reasoning_content=reasoning_content, - model_name=self.current_model_name) - + prompt=prompt, response=content, reasoning_content=reasoning_content, model_name=self.current_model_name + ) + except Exception: logger.exception("生成回复时出错") return None - return content - - async def _check_response_with_model(self, message: MessageRecv, content:str, model: LLM_request,thinking_id:str) -> str: - + + async def _check_response_with_model( + self, message: MessageRecv, content: str, model: LLM_request, thinking_id: str + ) -> str: _info_catcher = info_catcher_manager.get_info_catcher(thinking_id) - + sender_name = "" if message.chat_stream.user_info.user_cardname and message.chat_stream.user_info.user_nickname: sender_name = ( @@ -145,36 +149,32 @@ class ResponseGenerator: sender_name = f"({message.chat_stream.user_info.user_id}){message.chat_stream.user_info.user_nickname}" else: sender_name = f"用户({message.chat_stream.user_info.user_id})" - - + # 构建prompt - timer1 = time.time() - prompt = await prompt_builder._build_prompt_check_response( - message.chat_stream, - message_txt=message.processed_plain_text, - sender_name=sender_name, - stream_id=message.chat_stream.stream_id, - content=content - ) - timer2 = time.time() + with Timer() as t_build_prompt_check: + prompt = await prompt_builder._build_prompt_check_response( + message.chat_stream, + message_txt=message.processed_plain_text, + sender_name=sender_name, + stream_id=message.chat_stream.stream_id, + content=content, + ) logger.info(f"构建check_prompt: {prompt}") - logger.info(f"构建check_prompt时间: {timer2 - timer1}秒") + logger.info(f"构建check_prompt时间: {t_build_prompt_check.human_readable()}") try: checked_content, reasoning_content, self.current_model_name = await model.generate_response(prompt) - - + # info_catcher.catch_after_llm_generated( # prompt=prompt, # response=content, # reasoning_content=reasoning_content, # model_name=self.current_model_name) - + except Exception: logger.exception("检查回复时出错") return None - return checked_content async def _get_emotion_tags(self, content: str, processed_plain_text: str): diff --git a/src/plugins/utils/timer_calculater.py b/src/plugins/utils/timer_calculater.py new file mode 100644 index 000000000..97f983268 --- /dev/null +++ b/src/plugins/utils/timer_calculater.py @@ -0,0 +1,58 @@ +from time import perf_counter +from typing import Dict, Optional + +""" +计时器:用于性能计时 + +感谢D指导 +""" +class TimerTypeError(TypeError): + """自定义类型错误异常""" + def __init__(self, param_name, expected_type, actual_type): + super().__init__( + f"Invalid type for '{param_name}'. " + f"Expected {expected_type}, got {actual_type.__name__}" + ) + +class Timer: + def __init__(self, name: Optional[str] = None, storage: Optional[Dict[str, float]] = None): + self.name = name # 计时器名称 + self.storage = storage # 计时结果存储 + self.elapsed = None # 计时结果 + + def _validate_types(self, name, storage): + """类型验证核心方法""" + # 验证 name 类型 + if name is not None and not isinstance(name, str): + raise TimerTypeError( + param_name="name", + expected_type="Optional[str]", + actual_type=type(name) + ) + + # 验证 storage 类型 + if storage is not None and not isinstance(storage, dict): + raise TimerTypeError( + param_name="storage", + expected_type="Optional[Dict[str, float]]", + actual_type=type(storage) + ) + def __enter__(self): + self.start = perf_counter() + return self + + def __exit__(self, *args): + self.end = perf_counter() + self.elapsed = self.end - self.start + if isinstance(self.storage, dict) and self.name: + self.storage[self.name] = self.elapsed + + def get_result(self) -> float: + """安全获取计时结果""" + return self.elapsed or 0.0 + + def human_readable(self) -> str: + """返回人类可读时间格式""" + if self.elapsed >= 1: + return f"{self.elapsed:.2f}秒" + return f"{self.elapsed*1000:.2f}毫秒" From d9c6c40046a25f4e11912eadd255216fedf39637 Mon Sep 17 00:00:00 2001 From: SnowindMe <1945743455@qq.com> Date: Sat, 12 Apr 2025 20:52:07 +0800 Subject: [PATCH 02/14] ruff --- src/plugins/utils/timer_calculater.py | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/src/plugins/utils/timer_calculater.py b/src/plugins/utils/timer_calculater.py index 97f983268..da6fdb016 100644 --- a/src/plugins/utils/timer_calculater.py +++ b/src/plugins/utils/timer_calculater.py @@ -6,13 +6,14 @@ from typing import Dict, Optional 感谢D指导 """ + + class TimerTypeError(TypeError): """自定义类型错误异常""" + def __init__(self, param_name, expected_type, actual_type): - super().__init__( - f"Invalid type for '{param_name}'. " - f"Expected {expected_type}, got {actual_type.__name__}" - ) + super().__init__(f"Invalid type for '{param_name}'. Expected {expected_type}, got {actual_type.__name__}") + class Timer: def __init__(self, name: Optional[str] = None, storage: Optional[Dict[str, float]] = None): @@ -24,19 +25,14 @@ class Timer: """类型验证核心方法""" # 验证 name 类型 if name is not None and not isinstance(name, str): - raise TimerTypeError( - param_name="name", - expected_type="Optional[str]", - actual_type=type(name) - ) - + raise TimerTypeError(param_name="name", expected_type="Optional[str]", actual_type=type(name)) + # 验证 storage 类型 if storage is not None and not isinstance(storage, dict): raise TimerTypeError( - param_name="storage", - expected_type="Optional[Dict[str, float]]", - actual_type=type(storage) + param_name="storage", expected_type="Optional[Dict[str, float]]", actual_type=type(storage) ) + def __enter__(self): self.start = perf_counter() return self @@ -46,7 +42,7 @@ class Timer: self.elapsed = self.end - self.start if isinstance(self.storage, dict) and self.name: self.storage[self.name] = self.elapsed - + def get_result(self) -> float: """安全获取计时结果""" return self.elapsed or 0.0 @@ -55,4 +51,4 @@ class Timer: """返回人类可读时间格式""" if self.elapsed >= 1: return f"{self.elapsed:.2f}秒" - return f"{self.elapsed*1000:.2f}毫秒" + return f"{self.elapsed * 1000:.2f}毫秒" From 739ca7e6121ea2fbcf9ebdb7814c066903c86b3f Mon Sep 17 00:00:00 2001 From: SnowindMe <1945743455@qq.com> Date: Sat, 12 Apr 2025 21:24:43 +0800 Subject: [PATCH 03/14] =?UTF-8?q?=E5=BF=98=E4=BA=86=E5=8A=A0=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E6=A3=80=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/utils/timer_calculater.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/utils/timer_calculater.py b/src/plugins/utils/timer_calculater.py index da6fdb016..3ece1c0f7 100644 --- a/src/plugins/utils/timer_calculater.py +++ b/src/plugins/utils/timer_calculater.py @@ -17,6 +17,8 @@ class TimerTypeError(TypeError): class Timer: def __init__(self, name: Optional[str] = None, storage: Optional[Dict[str, float]] = None): + self._validate_types(name, storage) + self.name = name # 计时器名称 self.storage = storage # 计时结果存储 self.elapsed = None # 计时结果 From c60a08033777bcf25560bcb5579f98de258b98a1 Mon Sep 17 00:00:00 2001 From: SnowindMe <1945743455@qq.com> Date: Sat, 12 Apr 2025 22:25:13 +0800 Subject: [PATCH 04/14] =?UTF-8?q?=E6=94=AF=E6=8C=81=E4=B8=8A=E4=B8=8B?= =?UTF-8?q?=E6=96=87+=E8=A3=85=E9=A5=B0=E5=99=A8=E7=9A=84=E8=AE=A1?= =?UTF-8?q?=E6=97=B6=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../reasoning_chat/reasoning_generator.py | 3 +- .../think_flow_chat/think_flow_generator.py | 8 +- src/plugins/utils/timer_calculater.py | 89 ++++++++++++------- 3 files changed, 62 insertions(+), 38 deletions(-) diff --git a/src/plugins/chat_module/reasoning_chat/reasoning_generator.py b/src/plugins/chat_module/reasoning_chat/reasoning_generator.py index 25416a1d5..6a19e1018 100644 --- a/src/plugins/chat_module/reasoning_chat/reasoning_generator.py +++ b/src/plugins/chat_module/reasoning_chat/reasoning_generator.py @@ -1,4 +1,3 @@ -import time from typing import List, Optional, Tuple, Union import random @@ -90,7 +89,7 @@ class ResponseGenerator: sender_name=sender_name, stream_id=message.chat_stream.stream_id, ) - logger.info(f"构建prompt时间: {t_build_prompt.human_readable()}") + logger.info(f"构建prompt时间: {t_build_prompt.human_readable}") try: content, reasoning_content, self.current_model_name = await model.generate_response(prompt) diff --git a/src/plugins/chat_module/think_flow_chat/think_flow_generator.py b/src/plugins/chat_module/think_flow_chat/think_flow_generator.py index b682a4c5b..c02a81184 100644 --- a/src/plugins/chat_module/think_flow_chat/think_flow_generator.py +++ b/src/plugins/chat_module/think_flow_chat/think_flow_generator.py @@ -72,11 +72,11 @@ class ResponseGenerator: if model_response: if checked: logger.info( - f"{global_config.BOT_NICKNAME}的回复是:{model_response},思忖后,回复是:{model_checked_response},生成回复时间: {t_generate_response.human_readable()}" + f"{global_config.BOT_NICKNAME}的回复是:{model_response},思忖后,回复是:{model_checked_response},生成回复时间: {t_generate_response.human_readable}" ) else: logger.info( - f"{global_config.BOT_NICKNAME}的回复是:{model_response},生成回复时间: {t_generate_response.human_readable()}" + f"{global_config.BOT_NICKNAME}的回复是:{model_response},生成回复时间: {t_generate_response.human_readable}" ) model_processed_response = await self._process_response(model_checked_response) @@ -119,7 +119,7 @@ class ResponseGenerator: sender_name=sender_name, stream_id=message.chat_stream.stream_id, ) - logger.info(f"构建{mode}prompt时间: {t_build_prompt.human_readable()}") + logger.info(f"构建{mode}prompt时间: {t_build_prompt.human_readable}") try: content, reasoning_content, self.current_model_name = await model.generate_response(prompt) @@ -160,7 +160,7 @@ class ResponseGenerator: content=content, ) logger.info(f"构建check_prompt: {prompt}") - logger.info(f"构建check_prompt时间: {t_build_prompt_check.human_readable()}") + logger.info(f"构建check_prompt时间: {t_build_prompt_check.human_readable}") try: checked_content, reasoning_content, self.current_model_name = await model.generate_response(prompt) diff --git a/src/plugins/utils/timer_calculater.py b/src/plugins/utils/timer_calculater.py index 3ece1c0f7..227b817ee 100644 --- a/src/plugins/utils/timer_calculater.py +++ b/src/plugins/utils/timer_calculater.py @@ -1,56 +1,81 @@ from time import perf_counter -from typing import Dict, Optional - -""" -计时器:用于性能计时 - -感谢D指导 -""" +from functools import wraps +from typing import Optional, Dict, Callable +import asyncio class TimerTypeError(TypeError): - """自定义类型错误异常""" + """自定义类型错误""" - def __init__(self, param_name, expected_type, actual_type): - super().__init__(f"Invalid type for '{param_name}'. Expected {expected_type}, got {actual_type.__name__}") + def __init__(self, param, expected_type, actual_type): + super().__init__(f"参数 '{param}' 类型错误,期望 {expected_type},实际得到 {actual_type.__name__}") class Timer: - def __init__(self, name: Optional[str] = None, storage: Optional[Dict[str, float]] = None): + """支持多种模式的计时器(类型安全+人类可读)""" + + def __init__(self, name: Optional[str] = None, storage: Optional[Dict[str, float]] = None, auto_unit: bool = True): self._validate_types(name, storage) - self.name = name # 计时器名称 - self.storage = storage # 计时结果存储 - self.elapsed = None # 计时结果 + self.name = name + self.storage = storage + self.elapsed = None + self.auto_unit = auto_unit + self._is_context = False def _validate_types(self, name, storage): - """类型验证核心方法""" - # 验证 name 类型 + """类型检查""" if name is not None and not isinstance(name, str): - raise TimerTypeError(param_name="name", expected_type="Optional[str]", actual_type=type(name)) + raise TimerTypeError("name", "Optional[str]", type(name)) - # 验证 storage 类型 if storage is not None and not isinstance(storage, dict): - raise TimerTypeError( - param_name="storage", expected_type="Optional[Dict[str, float]]", actual_type=type(storage) - ) + raise TimerTypeError("storage", "Optional[dict]", type(storage)) + + def __call__(self, func: Optional[Callable] = None) -> Callable: + """装饰器模式""" + if func is None: + return lambda f: Timer(name=self.name or f.__name__, storage=self.storage, auto_unit=self.auto_unit)(f) + + @wraps(func) + async def async_wrapper(*args, **kwargs): + with self: + return await func(*args, **kwargs) + + @wraps(func) + def sync_wrapper(*args, **kwargs): + with self: + return func(*args, **kwargs) + + wrapper = async_wrapper if asyncio.iscoroutinefunction(func) else sync_wrapper + wrapper.__timer__ = self # 保留计时器引用 + return wrapper def __enter__(self): + """上下文管理器入口""" + self._is_context = True self.start = perf_counter() return self def __exit__(self, *args): - self.end = perf_counter() - self.elapsed = self.end - self.start - if isinstance(self.storage, dict) and self.name: + self.elapsed = perf_counter() - self.start + self._record_time() + self._is_context = False + return False + + def _record_time(self): + """记录时间""" + if self.storage is not None and self.name: self.storage[self.name] = self.elapsed - def get_result(self) -> float: - """安全获取计时结果""" - return self.elapsed or 0.0 - + @property def human_readable(self) -> str: - """返回人类可读时间格式""" - if self.elapsed >= 1: - return f"{self.elapsed:.2f}秒" - return f"{self.elapsed * 1000:.2f}毫秒" + """人类可读时间格式""" + if self.elapsed is None: + return "未计时" + + if self.auto_unit: + return f"{self.elapsed * 1000:.2f}毫秒" if self.elapsed < 1 else f"{self.elapsed:.2f}秒" + return f"{self.elapsed:.4f}秒" + + def __str__(self): + return f"" From 8ffe0fdf51e6fffe492ab6cb7a5e8137a73c7f39 Mon Sep 17 00:00:00 2001 From: SnowindMe <1945743455@qq.com> Date: Sat, 12 Apr 2025 22:26:43 +0800 Subject: [PATCH 05/14] =?UTF-8?q?=E6=94=B9=E4=BA=86=E4=B8=8B=E8=A7=A3?= =?UTF-8?q?=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/utils/timer_calculater.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/utils/timer_calculater.py b/src/plugins/utils/timer_calculater.py index 227b817ee..c3020bd08 100644 --- a/src/plugins/utils/timer_calculater.py +++ b/src/plugins/utils/timer_calculater.py @@ -12,7 +12,7 @@ class TimerTypeError(TypeError): class Timer: - """支持多种模式的计时器(类型安全+人类可读)""" + """支持上下文+装饰器的计时器""" def __init__(self, name: Optional[str] = None, storage: Optional[Dict[str, float]] = None, auto_unit: bool = True): self._validate_types(name, storage) From fc14b72e69fb722ed384f6d3f0ea4a23a6071015 Mon Sep 17 00:00:00 2001 From: SnowindMe <1945743455@qq.com> Date: Sat, 12 Apr 2025 22:53:06 +0800 Subject: [PATCH 06/14] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=BA=86=E4=B8=8B?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E8=A7=A3=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/utils/timer_calculater.py | 32 +++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/plugins/utils/timer_calculater.py b/src/plugins/utils/timer_calculater.py index c3020bd08..8fbb98728 100644 --- a/src/plugins/utils/timer_calculater.py +++ b/src/plugins/utils/timer_calculater.py @@ -3,6 +3,38 @@ from functools import wraps from typing import Optional, Dict, Callable import asyncio +""" +# 更好的计时器 +感谢D指导 + +# 用法: + +- +@Timer() +def func(): + pass + +- +time_dict = {} +@Timer("计数", time_dict) +def func(): + pass + +- +def func(): + with Timer() as t: + pass + +- +def func(): + time_dict = {} + with Timer("计数", time_dict) as t: + pass + +属性:human_readable +自定义错误:TimerTypeError +""" + class TimerTypeError(TypeError): """自定义类型错误""" From e37e678167a23adcd2c62fd7a5b9a55a2fa50df4 Mon Sep 17 00:00:00 2001 From: SnowindMe <1945743455@qq.com> Date: Sat, 12 Apr 2025 23:41:44 +0800 Subject: [PATCH 07/14] =?UTF-8?q?=E5=AE=8C=E5=96=84=E4=BA=86=E4=B8=8B?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E8=A7=A3=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/utils/timer_calculater.py | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/plugins/utils/timer_calculater.py b/src/plugins/utils/timer_calculater.py index 8fbb98728..e6491bc56 100644 --- a/src/plugins/utils/timer_calculater.py +++ b/src/plugins/utils/timer_calculater.py @@ -5,33 +5,39 @@ import asyncio """ # 更好的计时器 +支持上下文和装饰器 感谢D指导 # 用法: -- -@Timer() -def func(): - pass - -- +- 装饰器 time_dict = {} @Timer("计数", time_dict) def func(): pass +print(time_dict) -- +- 上下文_1 def func(): with Timer() as t: pass + print(t) + print(t.human_readable) -- +- 上下文_2 def func(): time_dict = {} - with Timer("计数", time_dict) as t: + with Timer("计数", time_dict): pass + print(time_dict) + +参数: +- name:计时器的名字,默认为None +- time_dict:计时器结果存储字典,默认为None +- auto_unit: 自动选择单位(为毫秒或秒/一直为秒),默认为True(为毫秒或秒) 属性:human_readable + 自定义错误:TimerTypeError """ From 76cc007315bbed2fb446bda7d3d0014e518b9849 Mon Sep 17 00:00:00 2001 From: SnowindMe <1945743455@qq.com> Date: Sun, 13 Apr 2025 01:19:34 +0800 Subject: [PATCH 08/14] =?UTF-8?q?=E6=81=A2=E5=A4=8D=E9=BB=98=E8=AE=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/utils/statistic.py | 2 +- (临时版)麦麦开始学习.bat | 4 ++-- (测试版)麦麦生成人格.bat | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/plugins/utils/statistic.py b/src/plugins/utils/statistic.py index 5029b1d94..4b9afff39 100644 --- a/src/plugins/utils/statistic.py +++ b/src/plugins/utils/statistic.py @@ -337,7 +337,7 @@ class LLMStatistics: stats_output = self._format_stats_section_lite( hour_stats, "最近1小时统计:详细信息见根目录文件:llm_statistics.txt" ) - logger.debug("\n" + stats_output + "\n" + "=" * 50) + logger.info("\n" + stats_output + "\n" + "=" * 50) except Exception: logger.exception("控制台统计数据输出失败") diff --git a/(临时版)麦麦开始学习.bat b/(临时版)麦麦开始学习.bat index 256da321f..c6f4cd57b 100644 --- a/(临时版)麦麦开始学习.bat +++ b/(临时版)麦麦开始学习.bat @@ -42,8 +42,8 @@ if errorlevel 2 ( echo Conda 环境 "!CONDA_ENV!" 激活成功 python src/plugins/zhishi/knowledge_library.py ) else ( - if exist "..\maibot_env\Scripts\python.exe" ( - ..\maibot_env\Scripts\python src/plugins/zhishi/knowledge_library.py + if exist "venvvenv\Scripts\python.exe" ( + venvvenv\Scripts\python src/plugins/zhishi/knowledge_library.py ) else ( echo ====================================== echo 错误: venv环境不存在,请先创建虚拟环境 diff --git a/(测试版)麦麦生成人格.bat b/(测试版)麦麦生成人格.bat index a04c0d0cc..d61c9a6ab 100644 --- a/(测试版)麦麦生成人格.bat +++ b/(测试版)麦麦生成人格.bat @@ -42,8 +42,8 @@ if errorlevel 2 ( echo Conda 环境 "!CONDA_ENV!" 激活成功 python src/individuality/per_bf_gen.py ) else ( - if exist "..\maibot_env\Scripts\python.exe" ( - ..\maibot_env\Scripts\python src/individuality/per_bf_gen.py + if exist "venv\Scripts\python.exe" ( + venvvenv\Scripts\python src/individuality/per_bf_gen.py ) else ( echo ====================================== echo 错误: venv环境不存在,请先创建虚拟环境 From b3b7fbed848a20af428d14a2b22e3beca9e9ee7f Mon Sep 17 00:00:00 2001 From: SnowindMe <1945743455@qq.com> Date: Sun, 13 Apr 2025 01:20:48 +0800 Subject: [PATCH 09/14] =?UTF-8?q?=E6=81=A2=E5=A4=8D=E9=BB=98=E8=AE=A4x2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- (临时版)麦麦开始学习.bat | 4 ++-- (测试版)麦麦生成人格.bat | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/(临时版)麦麦开始学习.bat b/(临时版)麦麦开始学习.bat index c6f4cd57b..f96d7cfdc 100644 --- a/(临时版)麦麦开始学习.bat +++ b/(临时版)麦麦开始学习.bat @@ -42,8 +42,8 @@ if errorlevel 2 ( echo Conda 环境 "!CONDA_ENV!" 激活成功 python src/plugins/zhishi/knowledge_library.py ) else ( - if exist "venvvenv\Scripts\python.exe" ( - venvvenv\Scripts\python src/plugins/zhishi/knowledge_library.py + if exist "venv\Scripts\python.exe" ( + venv\Scripts\python src/plugins/zhishi/knowledge_library.py ) else ( echo ====================================== echo 错误: venv环境不存在,请先创建虚拟环境 diff --git a/(测试版)麦麦生成人格.bat b/(测试版)麦麦生成人格.bat index d61c9a6ab..e2aa5c06a 100644 --- a/(测试版)麦麦生成人格.bat +++ b/(测试版)麦麦生成人格.bat @@ -43,7 +43,7 @@ if errorlevel 2 ( python src/individuality/per_bf_gen.py ) else ( if exist "venv\Scripts\python.exe" ( - venvvenv\Scripts\python src/individuality/per_bf_gen.py + venv\Scripts\python src/individuality/per_bf_gen.py ) else ( echo ====================================== echo 错误: venv环境不存在,请先创建虚拟环境 From 886707b3f5a32af9b666293fea43a6017baa7b99 Mon Sep 17 00:00:00 2001 From: SnowindMe <1945743455@qq.com> Date: Sun, 13 Apr 2025 01:25:16 +0800 Subject: [PATCH 10/14] =?UTF-8?q?=E6=B7=BB=E5=8A=A0gitignore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index c2fb389ec..f82eb2b75 100644 --- a/.gitignore +++ b/.gitignore @@ -237,3 +237,6 @@ logs /config/* run_none.bat config/old/bot_config_20250405_212257.toml +(测试版)麦麦生成人格.bat +(临时版)麦麦开始学习.bat +src/plugins/utils/statistic.py From ee6f451a69e95e25d11ced18aac2681ecc683aa8 Mon Sep 17 00:00:00 2001 From: SnowindMe <1945743455@qq.com> Date: Sun, 13 Apr 2025 01:29:06 +0800 Subject: [PATCH 11/14] gitignore --- .gitignore | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index f82eb2b75..2dec25d69 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,9 @@ config/bot_config.toml config/bot_config.toml.bak src/plugins/remote/client_uuid.json run_none.bat +(测试版)麦麦生成人格.bat +(临时版)麦麦开始学习.bat +src/plugins/utils/statistic.py # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] @@ -237,6 +240,4 @@ logs /config/* run_none.bat config/old/bot_config_20250405_212257.toml -(测试版)麦麦生成人格.bat -(临时版)麦麦开始学习.bat -src/plugins/utils/statistic.py + From 2d235330e9316846e0bbd0ccbed2e5741b0a6960 Mon Sep 17 00:00:00 2001 From: SnowindMe <1945743455@qq.com> Date: Sun, 13 Apr 2025 02:28:48 +0800 Subject: [PATCH 12/14] =?UTF-8?q?=E5=86=8D=E6=94=B9=E4=B8=80=E7=89=88?= =?UTF-8?q?=E8=AE=A1=E6=97=B6=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/utils/timer_calculater.py | 43 +++++++++++++++++---------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/src/plugins/utils/timer_calculater.py b/src/plugins/utils/timer_calculater.py index e6491bc56..f71824b2f 100644 --- a/src/plugins/utils/timer_calculater.py +++ b/src/plugins/utils/timer_calculater.py @@ -6,36 +6,39 @@ import asyncio """ # 更好的计时器 支持上下文和装饰器 -感谢D指导 -# 用法: +使用方式: -- 装饰器 +【装饰器】 time_dict = {} @Timer("计数", time_dict) def func(): pass print(time_dict) -- 上下文_1 +【上下文_1】 def func(): with Timer() as t: pass print(t) - print(t.human_readable) + print(t.human_readable) -- 上下文_2 +【上下文_2】 def func(): time_dict = {} with Timer("计数", time_dict): pass print(time_dict) -参数: -- name:计时器的名字,默认为None -- time_dict:计时器结果存储字典,默认为None -- auto_unit: 自动选择单位(为毫秒或秒/一直为秒),默认为True(为毫秒或秒) +【直接实例化】 +a = Timer() +print(a) # 直接输出当前 perf_counter 值 +参数: +- name:计时器的名字,默认为 None +- storage:计时器结果存储字典,默认为 None +- auto_unit:自动选择单位(毫秒或秒),默认为 True(自动根据时间切换毫秒或秒) + 属性:human_readable 自定义错误:TimerTypeError @@ -50,7 +53,12 @@ class TimerTypeError(TypeError): class Timer: - """支持上下文+装饰器的计时器""" + """ + Timer 支持三种模式: + 1. 装饰器模式:用于测量函数/协程运行时间 + 2. 上下文管理器模式:用于 with 语句块内部计时 + 3. 直接实例化:如果不调用 __enter__,打印对象时将显示当前 perf_counter 的值 + """ def __init__(self, name: Optional[str] = None, storage: Optional[Dict[str, float]] = None, auto_unit: bool = True): self._validate_types(name, storage) @@ -59,7 +67,6 @@ class Timer: self.storage = storage self.elapsed = None self.auto_unit = auto_unit - self._is_context = False def _validate_types(self, name, storage): """类型检查""" @@ -90,14 +97,12 @@ class Timer: def __enter__(self): """上下文管理器入口""" - self._is_context = True self.start = perf_counter() return self def __exit__(self, *args): self.elapsed = perf_counter() - self.start self._record_time() - self._is_context = False return False def _record_time(self): @@ -116,4 +121,12 @@ class Timer: return f"{self.elapsed:.4f}秒" def __str__(self): - return f"" + if hasattr(self, "start"): + if self.elapsed is None: + # 如果计时尚未结束,显示当前经过时间 + current_elapsed = perf_counter() - self.start + return f"" + return f"" + else: + # 未使用 as 上下文,直接返回当前 perf_counter() + return f"{perf_counter()}" From a006af2548ea1d277f86b32e698e10501ac4765a Mon Sep 17 00:00:00 2001 From: SnowindMe <1945743455@qq.com> Date: Sun, 13 Apr 2025 02:45:15 +0800 Subject: [PATCH 13/14] =?UTF-8?q?=E5=AE=8C=E5=96=84=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/utils/timer_calculater.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/plugins/utils/timer_calculater.py b/src/plugins/utils/timer_calculater.py index f71824b2f..ca6ad90b3 100644 --- a/src/plugins/utils/timer_calculater.py +++ b/src/plugins/utils/timer_calculater.py @@ -5,7 +5,15 @@ import asyncio """ # 更好的计时器 -支持上下文和装饰器 + +使用形式: +- 上下文 +- 装饰器 +- 直接实例化 + +使用场景: +- 使用Timer:在需要测量代码执行时间时(如性能测试、计时器工具),Timer类是更可靠、高精度的选择。 +- 使用time.time()的场景:当需要记录实际时间点(如日志、时间戳)时使用,但避免用它测量时间间隔。 使用方式: From c5e8ca33d093dd88c1678d7bbc6ef08a14b1a0a1 Mon Sep 17 00:00:00 2001 From: SnowindMe <1945743455@qq.com> Date: Sun, 13 Apr 2025 03:06:42 +0800 Subject: [PATCH 14/14] =?UTF-8?q?=E5=B0=8F=E4=BC=98=E5=8C=96=E4=B8=80?= =?UTF-8?q?=E4=B8=8B=E6=80=A7=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/plugins/utils/timer_calculater.py | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/plugins/utils/timer_calculater.py b/src/plugins/utils/timer_calculater.py index ca6ad90b3..aa12f35ce 100644 --- a/src/plugins/utils/timer_calculater.py +++ b/src/plugins/utils/timer_calculater.py @@ -46,6 +46,7 @@ print(a) # 直接输出当前 perf_counter 值 - name:计时器的名字,默认为 None - storage:计时器结果存储字典,默认为 None - auto_unit:自动选择单位(毫秒或秒),默认为 True(自动根据时间切换毫秒或秒) +- do_type_check:是否进行类型检查,默认为 False(不进行类型检查) 属性:human_readable @@ -56,6 +57,8 @@ print(a) # 直接输出当前 perf_counter 值 class TimerTypeError(TypeError): """自定义类型错误""" + __slots__ = () + def __init__(self, param, expected_type, actual_type): super().__init__(f"参数 '{param}' 类型错误,期望 {expected_type},实际得到 {actual_type.__name__}") @@ -68,13 +71,24 @@ class Timer: 3. 直接实例化:如果不调用 __enter__,打印对象时将显示当前 perf_counter 的值 """ - def __init__(self, name: Optional[str] = None, storage: Optional[Dict[str, float]] = None, auto_unit: bool = True): - self._validate_types(name, storage) + __slots__ = ("name", "storage", "elapsed", "auto_unit", "start") + + def __init__( + self, + name: Optional[str] = None, + storage: Optional[Dict[str, float]] = None, + auto_unit: bool = True, + do_type_check: bool = False, + ): + if do_type_check: + self._validate_types(name, storage) self.name = name self.storage = storage self.elapsed = None + self.auto_unit = auto_unit + self.start = None def _validate_types(self, name, storage): """类型检查""" @@ -129,12 +143,9 @@ class Timer: return f"{self.elapsed:.4f}秒" def __str__(self): - if hasattr(self, "start"): + if self.start is not None: if self.elapsed is None: - # 如果计时尚未结束,显示当前经过时间 current_elapsed = perf_counter() - self.start return f"" return f"" - else: - # 未使用 as 上下文,直接返回当前 perf_counter() - return f"{perf_counter()}" + return f"{perf_counter()}"