Помните, что C ++ использует принцип «не платите за то, что вы не используете». Рассмотрим, например, мнимую платформу, которая использует непрозрачный тип для представления мьютекса; назовем этот тип mutex_t
. Если интерфейс для работы с этим мьютеком использует mutex_t*
в качестве аргументов, например, как void mutex_init(mutex_t* mutex);
для «создания» мьютекса, вполне может случиться так, что адрес мьютекса - это то, что используется для однозначной идентификации мьютекса. Если это так, то это означает, что mutex_t
не копируется:
mutex_t kaboom()
{
mutex_t mutex;
mutex_init(&mutex);
return mutex; // disaster
}
Здесь нет никакой гарантии при выполнении mutex_t mutex = kaboom();
, что &mutex
имеет то же значение, что и &mutex
в функциональный блок.
Когда приходит день, когда разработчик хочет записать std::mutex
для этой платформы, если требования этого типа будут подвижными, то это означает, что внутренний mutex_t
должен быть помещен в динамически распределенной памяти со всеми связанными штрафами.
С другой стороны, хотя сейчас std::mutex
является not подвижным, очень легко «вернуть» один из функция: верните std::unique_ptr<std::mutex>
. Это все еще оплачивает затраты на динамическое распределение , но только в одном месте . Все остальные коды, которые не должны перемещать std::mutex
, не должны оплачивать это.
Другими словами, поскольку перемещение мьютекса не является основной операцией того, что означает мьютекс , не требуя перемещения std::mutex
, не снимает никаких функциональных возможностей (благодаря не подвижной T
=> подвижной std::unique_ptr<T>
трансформации) и будет понести минимальные накладные расходы по сравнению с использованием собственного типа.
std::thread
можно было бы аналогичным образом указать, чтобы он не был подвижным, что сделало бы типичное время жизни как таковое: running (связанный с потоком выполнение) после вызова конструктора с оценкой; и отсоединены / объединены (не связаны нитями выполнения), после вызова join
или detach
. Насколько я понимаю, std::vector<std::thread>
все равно был бы полезен, так как тип был бы EmplaceConstructible
.
edit: Неверно! Тип все равно должен быть подвижным (при перераспределении в конце концов). Для меня это достаточно обосновано: типично помещать std::thread
в контейнеры, такие как std::vector
и std::deque
, поэтому функциональность приветствуется для этого типа.
my_array = ["Some_xyz_process",
"Start", "2018-07-12", "12:59:53,397",
"End", "2018-07-12", "12:59:55,913"]
require 'date'
fmt = '%Y-%m-%d%H:%M:%S,%L'
is = my_array.index('Start')
#=> 1
ie = my_array.index('End')
#=> 4
DateTime.strptime(my_array[ie+1] + my_array[ie+2], fmt).to_time -
DateTime.strptime(my_array[is+1] + my_array[is+2], fmt).to_time
#=> 2.516 (seconds)
См. DateTime # strptime и DateTime # (последнее для директив формата). Пока известны форматы даты и времени, я всегда предпочитаю strptime
- parse
. Вот пример того, почему:
DateTime.parse 'Theresa May has had a bad week over Brexit'
#=> #<DateTime: 2018-05-01T00:00:00+00:00 ((2458240j,0s,0n),+0s,2299161j)>`.
Вы можете согласовать поле даты и времени и использовать Time.parse
, чтобы преобразовать его в объект времени, а затем вычислить разницу в количестве секунд
Time.parse('2018-07-12 12:59:55,397').to_i - Time.parse('2018-07-12 12:59:53,913').to_i
Надеемся, что это поможет
DateTime#parse
может сходить с ума. – Jagdeep Singh 13 July 2018 в 10:12