【问题标题】:Time in milliseconds in CC中的时间(以毫秒为单位)
【发布时间】:2012-04-28 21:23:33
【问题描述】:

使用以下代码:

#include<stdio.h>
#include<time.h>
int main()
{
    clock_t start, stop;
    int i;
    start = clock();
    for(i=0; i<2000;i++)
    {
        printf("%d", (i*1)+(1^4));
    }
    printf("\n\n");
    stop = clock();

    //(double)(stop - start) / CLOCKS_PER_SEC

    printf("%6.3f", start);
    printf("\n\n%6.3f", stop);
    return 0;
}

我得到以下输出:

5678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037 1372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704 7057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102 8102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127 8127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152 8152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177 81779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004 2.169 2.169
  1. 开始和停止时间相同。是不是意味着程序几乎不需要时间来完成执行?

  2. 如果 1. 为假,则至少 (.) 之外的位数应该不同,这里不会发生这种情况。我的逻辑对吗?

注意:我需要计算执行所花费的时间,以及上面的代码。

【问题讨论】:

  • C11 允许使用timespec_get: stackoverflow.com/a/36095407/895245 达到纳秒级的分辨率
  • 它也是或可能是特定于操作系统和计算机的。在 Linux 上读取 time(7)。在 Windows 上,据传clock() 有缺陷(测量实时,而不是 CPU 时间)。

标签: c time clock


【解决方案1】:

是的,这个程序可能用了不到一毫秒。尝试使用 timeval 的微秒分辨率。

例如:

#include <sys/time.h>

struct timeval stop, start;
gettimeofday(&start, NULL);
//do stuff
gettimeofday(&stop, NULL);
printf("took %lu us\n", (stop.tv_sec - start.tv_sec) * 1000000 + stop.tv_usec - start.tv_usec); 

然后您可以查询stop.tv_usec - start.tv_usec 之间的差异(以微秒为单位)。请注意,这仅适用于亚秒级时间(因为tv_usec 将循环)。对于一般情况,请结合使用 tv_sectv_usec

编辑 2016-08-19

在支持clock_gettime 的系统上更合适的方法是:

struct timespec start, end;
clock_gettime(CLOCK_MONOTONIC_RAW, &start);
//do stuff
clock_gettime(CLOCK_MONOTONIC_RAW, &end);

uint64_t delta_us = (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_nsec - start.tv_nsec) / 1000;

【讨论】:

  • 别忘了用struct timeval代替timeval;前者可能是@cmh 的意思,而后者会导致编译错误。
  • @InkBlend:你当然是对的。我已经习惯用 c++ 编码,在这种情况下可以安全地省略 struct
  • tv_usec 将在每一秒开始时回绕回零。表达式“stop.tv_usec - start.tv_usec”将不起作用,因为无法预先知道每个样本在一秒钟内的哪个时间点。您需要同时使用 tv_sec 和 tv_usec,即使是亚秒级。
  • 请注意,在 2016 年 9 月发布 macOS Sierra 10.12 之前,Mac 上没有 clock_gettime()(Mac OS X 10.11 El Capitan 和更早的版本从未有过)。在 Sierra 之前,gettimeofday() 是该平台上最好的,除非您使用隐藏在 Mac(Objective C)框架等中的特殊功能。
  • @Elliott 本身并没有错,在 一些 系统上实现相同目标有更好的方法 - 但它在clock_gettime 不存在的任何地方仍然有效可用。
【解决方案2】:

这段代码sn-p可以用来显示时间,单位是秒、毫秒和微秒:

#include <sys/time.h>

struct timeval start, stop;
double secs = 0;

gettimeofday(&start, NULL);

// Do stuff  here

gettimeofday(&stop, NULL);
secs = (double)(stop.tv_usec - start.tv_usec) / 1000000 + (double)(stop.tv_sec - start.tv_sec);
printf("time taken %f\n",secs);

【讨论】:

    【解决方案3】:

    有几件事可能会影响您看到的结果:

    1. 您将clock_t 视为浮点类型,我认为不是。
    2. 您可能希望 (1^4) 执行其他操作,而不是按位计算 1 和 4 的 XOR,即它是 5。
    3. 由于 XOR 是常量,它可能是folded by the compiler,这意味着它不会在运行时增加很多工作。
    4. 由于输出是缓冲的(它只是格式化字符串并将其写入内存),它确实很快完成。

    你没有指定你的机器有多快,但在现代硬件上运行得非常快并不是不合理的,不。

    如果有,请尝试在开始/停止快照之间添加对 @987654323@ 的调用。请注意,sleep() 虽然是 POSIX,而不是标准 C。

    【讨论】:

    • 很好。这只是一个手术,我需要做的。
    • 但是,有时我确实会得到诸如 0.295 表示开始,0.497 表示停止的值。
    【解决方案4】:

    您可以使用gettimeofday() 和下面的timedifference_msec() 函数来计算两个样本之间经过的毫秒数:

    #include <sys/time.h>
    #include <stdio.h>
    
    float timedifference_msec(struct timeval t0, struct timeval t1)
    {
        return (t1.tv_sec - t0.tv_sec) * 1000.0f + (t1.tv_usec - t0.tv_usec) / 1000.0f;
    }
    
    int main(void)
    {
       struct timeval t0;
       struct timeval t1;
       float elapsed;
    
       gettimeofday(&t0, 0);
       /* ... YOUR CODE HERE ... */
       gettimeofday(&t1, 0);
    
       elapsed = timedifference_msec(t0, t1);
    
       printf("Code executed in %f milliseconds.\n", elapsed);
    
       return 0;
    }
    

    请注意,在使用gettimeofday() 时,即使您只关心微秒差异,您也需要考虑秒数,因为tv_usec 将每秒回零,您无法事先知道在哪个时间点获得每个样本的时间。

    【讨论】:

    • 只是一个提示:“POSIX.1-2008 将 gettimeofday() 标记为已过时,建议改用 clock_gettime(2)。” - 来自“man gettimeofday()”
    【解决方案5】:

    这是我写的以百万秒为单位的时间戳。

    #include<sys/time.h>
    
    long long timeInMilliseconds(void) {
        struct timeval tv;
    
        gettimeofday(&tv,NULL);
        return (((long long)tv.tv_sec)*1000)+(tv.tv_usec/1000);
    }
    

    【讨论】:

    • 最后一个简单的解决方案,返回毫秒,非常感谢!对我来说效果很好
    【解决方案6】:

    来自man clock

    clock() 函数返回程序使用的处理器时间的近似值。

    因此没有迹象表明您应该将其视为毫秒。一些标准需要精确的 CLOCKS_PER_SEC 值,因此您可以依赖它,但我不认为这是可取的。 第二件事是,正如@unwind 所说,它不是浮点数/双精度数。 Man times 建议这将是一个 int。 另请注意:

    此函数将大约每 72 分钟返回一次相同的值

    如果你运气不好,你可能会碰到它即将从零开始计数的时刻,从而得到负值或巨大值(取决于你将结果存储为有符号值还是无符号值)。

    这个:

    printf("\n\n%6.3f", stop);
    

    很可能会打印垃圾,因为将任何 int 视为 float 确实是未定义的行为(我认为这是您的大部分问题所在)。如果您想确保始终可以做到:

    printf("\n\n%6.3f", (double) stop);
    

    虽然我宁愿一开始将其打印为long long int

    printf("\n\n%lldf", (long long int) stop);
    

    【讨论】:

    • 我也使用了你的第二个,但仍然得到相同的结果。
    • 我的意思是,无论你在 C++ 中给出的代码是否与 C 相同。
    • 是的,使用 C++ 的唯一原因是我不必在打印时猜测 clock_t 的类型。
    【解决方案7】:

    标准 C 库提供timespec_get。如果系统支持,它可以将时间精确到纳秒。然而,调用它需要更多的努力,因为它涉及一个结构。这是一个函数,它只是将结构转换为简单的 64 位整数,因此您可以获得以毫秒为单位的时间。

    #include <stdio.h>
    #include <inttypes.h>
    #include <time.h>
    
    int64_t millis()
    {
        struct timespec now;
        timespec_get(&now, TIME_UTC);
        return ((int64_t) now.tv_sec) * 1000 + ((int64_t) now.tv_nsec) / 1000000;
    }
    
    int main(void)
    {
        printf("Unix timestamp with millisecond precision: %" PRId64 "\n", millis());
    }
    

    clock 不同,此函数返回一个 Unix 时间戳,因此它可以正确计算阻塞函数所花费的时间,例如 sleep

    【讨论】:

    • $ cc -std=c11 temp.c - temp.c:8:5: warning: implicit declaration of function 'timespec_get' is invalid in C99
    【解决方案8】:

    现代处理器速度太快,无法记录运行时间。因此它可能返回零。在这种情况下,您开始和结束的时间太小,因此在一轮之后两个时间都相同。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-27
      • 1970-01-01
      • 2019-09-11
      • 1970-01-01
      • 1970-01-01
      • 2011-04-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多