2015-06-08 2 views
-1

У меня есть класс таймера, который использует функцию запуска/остановки, и я использую внутренний вызов GetCurrentTimeAsUnixMillis(), который возвращает UInt64.Создание таймера и попытка конвертировать UInt64 в допустимую строку времени

Моя цель состоит в том, чтобы создать строку в формате: HH:MM:SS:mmm

Наивный подход, который я думал, было:

auto start = GetCurrentTimeAsUnixMillis(); 
auto end = GetCurrentTimeAsUnixMillis(); 
auto value = end - start; //gets the difference between start and stop. 
auto ms = 1; 
auto s = ms*1000; 
auto m = s*60; 
auto h = m*60; 

Utf8String out(""); 
out += value/h + ":"; 
value -= value/h; 
out += value/m + ":"; 
value -= value/m; 
out += value/s + ":"; 
value -= value/s; 
out += value; 

return out; 

Я просто думаю, что это слишком много вычислений и поэтому неправильный ответ.

+0

Предположим, что есть вызов библиотеки, который вы могли бы сделать вместо этого, считаете ли вы, что для вызова не нужно будет делать все те же математику? Вы должны сделать константы 'ms',' s' и т. Д., Они не будут меняться. Возможно, вам захочется подумать о том, как вы делаете форматирование, хотя, если вы хотите что-то вроде '01: 02: 03: 004'. Ваш код не добавляет начальные нули. –

+0

Да и нет. Я знаю, что он назвал бы похожий код, но когда вы будете обращаться к библиотекам, особенно к тем, которые являются std, он будет оптимизирован и, возможно, будет разрешен с использованием битхифта или целочисленного деления. – Fallenreaper

+0

Вы имеете в виду, что получаете неправильный результат, или что вы чувствуете, что есть более эффективный способ сделать это? В зависимости от того, что такое 'Utf8String', может быть, вы можете выделить достаточное пространство для размещения выходной строки? Если это невозможно, объявление локального буфера с использованием 'snprintf' для печати всех значений в нем, а затем создание« Utf8String »из буфера может быть более эффективным. – Praetorian

ответ

2

Не могу утверждать, что это определенно быстрее, но это более современно, я полагаю.

auto elapsed = std::chrono::milliseconds{end-start}; 

auto h = std::chrono::duration_cast<std::chrono::hours>(elapsed); 
auto m = std::chrono::duration_cast<std::chrono::minutes>(elapsed); 
auto s = std::chrono::duration_cast<std::chrono::seconds>(elapsed); 
auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(elapsed); 

ms -= s; 
s -= m; 
m -= h; 

// format using h.count(), m.count(), s.count(), ms.count() 
+0

Дэйв, я продолжаю получать: 'std :: chrono' не был объявлен. Мысли? – Fallenreaper

+0

@Fallenreaper '#include ' – David

0

Трудно перехитрить оптимизатор. Я бы, вероятно, каскадировал modulo и division, и попытался сделать форматирование одним вызовом, но я не уверен, что это возможно с Utf8String, так как я не знаком с ним.

// start with millisecond 
auto ms = value % 1000; 
value /= 1000; 
// now second 
auto s = value % 60; 
value /= 60; 
// now minute 
auto m = value % 60; 
value /= 60; 
// now hour 
auto h = value; 
//... formatting the output left as an exercise ... 
Смежные вопросы