# Про замер времени

В Python для наиболее точного измерения времени можно использовать несколько подходов в зависимости от контекста и требований к точности. Вот основные методы, упорядоченные по точности:

#### 1. **`time.perf_counter()`** (наиболее точный для интервалов)

```python
import time

start = time.perf_counter()
# Ваш код
elapsed = time.perf_counter() - start
print(f"Время выполнения: {elapsed:.6f} секунд")
```

* Возвращает время в секундах с максимально доступной точностью
* Использует монотонные часы (не подвержены корректировкам системного времени)
* Рекомендован для измерения интервалов

#### 2. **`time.time_ns()`** (наносекундная точность)

```python
import time

start = time.time_ns()
# Ваш код
elapsed_ns = time.time_ns() - start
print(f"Время выполнения: {elapsed_ns / 1e9:.9f} секунд")
```

* Возвращает время в наносекундах (Python 3.7+)
* Менее точен чем `perf_counter()` для измерения интервалов, так как зависит от системных часов

#### 3. **Для ROS 2 (используя rclpy)**

```python
from rclpy.clock import Clock

clock = Clock()
start = clock.now()
# Ваш код
elapsed = (clock.now() - start).nanoseconds * 1e-9
print(f"Время выполнения: {elapsed:.9f} секунд")
```

* Интегрировано с ROS 2 временем
* Поддерживает разные типы времени (ROS, системное, монотонное)

#### 4. **Профилирование маленьких интервалов (CPU циклы)**

Для микрооптимизаций можно использовать `time.process_time()` (только CPU время) или даже низкоуровневые методы:

```python
import timeit

code_to_test = """
# Ваш небольшой фрагмент кода
result = sum(range(1000))
"""

elapsed = timeit.timeit(code_to_test, number=10000) / 10000
print(f"Среднее время: {elapsed:.9f} сек")
```

#### Ваш случай в ROS 2 ноде:

Для вашей ноды лучше всего использовать встроенные механизмы ROS 2:

```python
def timer_callback(self):
    now = self.get_clock().now()
    time_since_last_msg = (now - self.last_msg_time).nanoseconds * 1e-9
    time_since_last_msg = (now - self.last_msg_time).seconds
    
    if time_since_last_msg > self.timeout:
        # ... ваш код
```

#### Почему `perf_counter()` лучше для интервалов?

* Не зависит от корректировок системного времени
* Максимально возможная точность на данной платформе
* В Windows точность \~1 мкс, в Linux \~1 нс

#### Пример точного замера:

```python
import time

def measure():
    start = time.perf_counter()
    time.sleep(0.001)  # Имитация работы
    return time.perf_counter() - start

# Усреднение для точности
results = [measure() for _ in range(1000)]
print(f"Среднее: {sum(results)/len(results):.9f} сек")
```

Выбор метода зависит от ваших требований:

* Для ROS 2 нод - используйте `self.get_clock().now()`
* Для обычного Python кода - `time.perf_counter()`
* Для микрооптимизаций - `timeit` или `time.process_time()`

В ROS2 (Robot Operating System 2) можно засечь время несколькими способами, в зависимости от того, нужно ли вам:

* **Текущее системное время** (как в обычном Python).
* **ROS2-время** (с учетом симуляции `/clock`, если используется `use_sim_time`).
* **Измерение интервалов времени** (таймеры, замеры производительности).

***

### **1. Текущее время (системное или ROS2)**

#### **1.1. Системное время (как в обычном Python)**

```python
import time

current_time_sec = time.time()  # время в секундах с эпохи Unix
current_time_ns = time.time_ns()  # время в наносекундах
print(f"Current time: {current_time_sec} sec, {current_time_ns} ns")
```

#### **1.2. ROS2-время (`rclpy.time`)**

Если ваш ROS2-узел использует `/clock` (например, в симуляции Gazebo), лучше работать через `rclpy.time`:

```python
import rclpy
from rclpy.time import Time

node = rclpy.create_node('time_example')
ros_time = node.get_clock().now()  # возвращает Time объект

# Преобразование в секунды, наносекунды и т.д.
print(f"ROS Time: {ros_time}")  # Time(nanoseconds=...)
print(f"ROS Time (sec): {ros_time.nanoseconds / 1e9}")
```

***

### **2. Замер времени выполнения (таймеры)**

#### **2.1. Простой замер интервала (Python)**

```python
import time

start_time = time.time()
# ... ваш код ...
elapsed_time = time.time() - start_time
print(f"Execution time: {elapsed_time} sec")
```

#### **2.2. ROS2-таймер (`rclpy.timer`)**

Если нужно периодически выполнять код:

```python
import rclpy
from rclpy.node import Node

class TimerNode(Node):
    def __init__(self):
        super().__init__('timer_example')
        self.timer = self.create_timer(1.0, self.timer_callback)  # 1 Hz
    
    def timer_callback(self):
        self.get_logger().info("Timer triggered!")

rclpy.init()
node = TimerNode()
rclpy.spin(node)
```

#### **2.3. Замер времени между событиями (используя `rclpy.time`)**

```python
import rclpy
from rclpy.time import Time

node = rclpy.create_node('time_measurement')
start_time = node.get_clock().now()

# ... ваш код ...

end_time = node.get_clock().now()
duration = end_time - start_time  # Duration объект
print(f"Duration: {duration.nanoseconds / 1e9} sec")
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://alice-and-alex-docs.gitbook.io/alice_and_alex_docs/ros2-development/pro-zamer-vremeni.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
