348

我正在尝试使用time()来测量程序的各个点。

我不明白的是为什么之前和之后的值是一样的?我知道这不是分析我的程序的最佳方式,我只是想看看需要多长时间。

printf("**MyProgram::before time= %ld\n", time(NULL));

doSomthing();
doSomthingLong();

printf("**MyProgram::after time= %ld\n", time(NULL));

我努力了:

struct timeval diff, startTV, endTV;

gettimeofday(&startTV, NULL); 

doSomething();
doSomethingLong();

gettimeofday(&endTV, NULL); 

timersub(&endTV, &startTV, &diff);

printf("**time taken = %ld %ld\n", diff.tv_sec, diff.tv_usec);

我如何阅读结果**time taken = 0 26339?这是否意味着 26,339 纳秒 = 26.3 毫秒?

那么**time taken = 4 45025,这是否意味着 4 秒和 25 毫秒?

4

25 回答 25

469
//***C++11 Style:***
#include <chrono>

std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();

std::cout << "Time difference = " << std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count() << "[µs]" << std::endl;
std::cout << "Time difference = " << std::chrono::duration_cast<std::chrono::nanoseconds> (end - begin).count() << "[ns]" << std::endl;
于 2015-01-02T09:27:30.047 回答
297

0 - 三角洲

使用 delta 函数计算时间差:

auto start = std::chrono::steady_clock::now();
std::cout << "Elapsed(ms)=" << since(start).count() << std::endl;

since接受任何时间点并产生任何持续时间(毫秒是默认值)。它被定义为:

template <
    class result_t   = std::chrono::milliseconds,
    class clock_t    = std::chrono::steady_clock,
    class duration_t = std::chrono::milliseconds
>
auto since(std::chrono::time_point<clock_t, duration_t> const& start)
{
    return std::chrono::duration_cast<result_t>(clock_t::now() - start);
}

Demo

1 - 定时器

使用基于以下的计时器std::chrono

Timer clock; // Timer<milliseconds, steady_clock>

clock.tick();
/* code you want to measure */
clock.tock();

cout << "Run time = " << clock.duration().count() << " ms\n";

Demo

Timer定义为:

template <class DT = std::chrono::milliseconds,
          class ClockT = std::chrono::steady_clock>
class Timer
{
    using timep_t = typename ClockT::time_point;
    timep_t _start = ClockT::now(), _end = {};

public:
    void tick() { 
        _end = timep_t{}; 
        _start = ClockT::now(); 
    }
    
    void tock() { _end = ClockT::now(); }
    
    template <class T = DT> 
    auto duration() const { 
        gsl_Expects(_end != timep_t{} && "toc before reporting"); 
        return std::chrono::duration_cast<T>(_end - _start); 
    }
};

正如Howard Hinnant所指出的,我们使用持续时间来保留在chrono类型系统中并执行诸如平均或比较之类的操作(例如,这里这意味着使用std::chrono::milliseconds)。当我们只做 IO 时,我们使用count()持续时间的或滴答声(例如这里的毫秒数)。

2 - 仪表

任何可调用(函数、函数对象、lambda 等)都可以用于基准测试。假设您有一个F可使用 arguments 调用的函数arg1,arg2,这种技术会导致:

cout << "F runtime=" << measure<>::duration(F, arg1, arg2).count() << "ms";

Demo

measure定义为:

template <class TimeT  = std::chrono::milliseconds
          class ClockT = std::chrono::steady_clock>
struct measure
{
    template<class F, class ...Args>
    static auto duration(F&& func, Args&&... args)
    {
        auto start = ClockT::now();
        std::invoke(std::forward<F>(func), std::forward<Args>(args)...);
        return std::chrono::duration_cast<TimeT>(ClockT::now()-start);
    }
};

如 (1) 中所述,使用无持续时间.count()对于希望在 I/O 之前对一堆持续时间进行后处理的客户端最有用,例如平均:

auto avg = (measure<>::duration(func) + measure<>::duration(func)) / 2;
std::cout << "Average run time " << avg.count() << " ms\n";

+就是转发函数调用的原因。

+完整的代码可以在这里找到

+我尝试建立一个基于chrono的基准测试框架记录在这里

+旧演示

于 2014-02-24T18:13:40.377 回答
284
#include <ctime>

void f() {
  using namespace std;
  clock_t begin = clock();

  code_to_time();

  clock_t end = clock();
  double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
}

The time() function is only accurate to within a second, but there are CLOCKS_PER_SEC "clocks" within a second. This is an easy, portable measurement, even though it's over-simplified.

于 2010-05-11T06:34:45.367 回答
59

正如我从您的问题中看到的那样,您似乎想知道执行某些代码后经过的时间。我想您会很乐意在几秒钟内看到结果。如果是这样,请尝试使用difftime()如下所示的函数。希望这能解决您的问题。

#include <time.h>
#include <stdio.h>

time_t start,end;
time (&start);
.
.
.
<your code>
.
.
.
time (&end);
double dif = difftime (end,start);
printf ("Elasped time is %.2lf seconds.", dif );
于 2010-05-11T07:57:33.573 回答
32

仅限 Windows:(在我发布此答案后添加了 Linux 标签)

您可以使用GetTickCount()获取自系统启动以来经过的毫秒数。

long int before = GetTickCount();

// Perform time-consuming operation

long int after = GetTickCount();
于 2010-05-11T06:22:02.880 回答
17
struct profiler
{
    std::string name;
    std::chrono::high_resolution_clock::time_point p;
    profiler(std::string const &n) :
        name(n), p(std::chrono::high_resolution_clock::now()) { }
    ~profiler()
    {
        using dura = std::chrono::duration<double>;
        auto d = std::chrono::high_resolution_clock::now() - p;
        std::cout << name << ": "
            << std::chrono::duration_cast<dura>(d).count()
            << std::endl;
    }
};

#define PROFILE_BLOCK(pbn) profiler _pfinstance(pbn)

用法如下::

{
    PROFILE_BLOCK("Some time");
    // your code or function
}

这在范围上类似于 RAII

注意这不是我的,但我认为它在这里是相关的

于 2016-06-03T06:46:21.637 回答
15

time(NULL)返回自 1970 年 1 月 1 日 00:00 ( Epoch )以来经过的秒数。因此,这两个值之间的差异是处理所用的秒数。

int t0 = time(NULL);
doSomthing();
doSomthingLong();
int t1 = time(NULL);

printf ("time = %d secs\n", t1 - t0);

您可以使用 获得更好的结果getttimeofday(),它以秒为单位返回当前时间,time()同样也以微秒为单位。

于 2010-05-11T06:18:10.627 回答
13

time(NULL) 函数将返回自 01/01/1970 00:00 以来经过的秒数。而且因为该函数在程序中的不同时间被调用,所以在 C++ 中它总是不同 的时间

于 2010-05-11T06:08:13.690 回答
9
#include<time.h> // for clock
#include<math.h> // for fmod
#include<cstdlib> //for system
#include <stdio.h> //for delay

using namespace std;

int main()
{


   clock_t t1,t2;

   t1=clock(); // first time capture

   // Now your time spanning loop or code goes here
   // i am first trying to display time elapsed every time loop runs

   int ddays=0; // d prefix is just to say that this variable will be used for display
   int dhh=0;
   int dmm=0;
   int dss=0;

   int loopcount = 1000 ; // just for demo your loop will be different of course

   for(float count=1;count<loopcount;count++)
   {

     t2=clock(); // we get the time now

     float difference= (((float)t2)-((float)t1)); // gives the time elapsed since t1 in milliseconds

    // now get the time elapsed in seconds

    float seconds = difference/1000; // float value of seconds
    if (seconds<(60*60*24)) // a day is not over
    {
        dss = fmod(seconds,60); // the remainder is seconds to be displayed
        float minutes= seconds/60;  // the total minutes in float
        dmm= fmod(minutes,60);  // the remainder are minutes to be displayed
        float hours= minutes/60; // the total hours in float
        dhh= hours;  // the hours to be displayed
        ddays=0;
    }
    else // we have reached the counting of days
    {
        float days = seconds/(24*60*60);
        ddays = (int)(days);
        float minutes= seconds/60;  // the total minutes in float
        dmm= fmod(minutes,60);  // the rmainder are minutes to be displayed
        float hours= minutes/60; // the total hours in float
        dhh= fmod (hours,24);  // the hours to be displayed

    }

    cout<<"Count Is : "<<count<<"Time Elapsed : "<<ddays<<" Days "<<dhh<<" hrs "<<dmm<<" mins "<<dss<<" secs";


    // the actual working code here,I have just put a delay function
    delay(1000);
    system("cls");

 } // end for loop

}// end of main 
于 2012-09-15T14:07:28.543 回答
8

第二个程序打印的值是秒和微秒。

0 26339 = 0.026'339 s =   26339 µs
4 45025 = 4.045'025 s = 4045025 µs
于 2010-05-11T07:19:03.760 回答
8
#include <ctime>
#include <cstdio>
#include <iostream>
#include <chrono>
#include <sys/time.h>
using namespace std;
using namespace std::chrono;

void f1()
{
  high_resolution_clock::time_point t1 = high_resolution_clock::now();
  high_resolution_clock::time_point t2 = high_resolution_clock::now();
  double dif = duration_cast<nanoseconds>( t2 - t1 ).count();
  printf ("Elasped time is %lf nanoseconds.\n", dif );
}

void f2()
{
  timespec ts1,ts2;
  clock_gettime(CLOCK_REALTIME, &ts1);
  clock_gettime(CLOCK_REALTIME, &ts2);
  double dif = double( ts2.tv_nsec - ts1.tv_nsec );
  printf ("Elasped time is %lf nanoseconds.\n", dif );
}

void f3()
{
  struct timeval t1,t0;
  gettimeofday(&t0, 0);
  gettimeofday(&t1, 0);
  double dif = double( (t1.tv_usec-t0.tv_usec)*1000);
  printf ("Elasped time is %lf nanoseconds.\n", dif );
}
void f4()
{
  high_resolution_clock::time_point t1 , t2;
  double diff = 0;
  t1 = high_resolution_clock::now() ;
  for(int i = 1; i <= 10 ; i++)
  {
    t2 = high_resolution_clock::now() ;
    diff+= duration_cast<nanoseconds>( t2 - t1 ).count();
    t1 = t2;
  }
  printf ("high_resolution_clock:: Elasped time is %lf nanoseconds.\n", diff/10 );
}

void f5()
{
  timespec ts1,ts2;
  double diff = 0;
  clock_gettime(CLOCK_REALTIME, &ts1);
  for(int i = 1; i <= 10 ; i++)
  {
    clock_gettime(CLOCK_REALTIME, &ts2);
    diff+= double( ts2.tv_nsec - ts1.tv_nsec );
    ts1 = ts2;
  }
  printf ("clock_gettime:: Elasped time is %lf nanoseconds.\n", diff/10 );
}

void f6()
{
  struct timeval t1,t2;
  double diff = 0;
  gettimeofday(&t1, 0);
  for(int i = 1; i <= 10 ; i++)
  {
    gettimeofday(&t2, 0);
    diff+= double( (t2.tv_usec-t1.tv_usec)*1000);
    t1 = t2;
  }
  printf ("gettimeofday:: Elasped time is %lf nanoseconds.\n", diff/10 );
}

int main()
{
  //  f1();
  //  f2();
  //  f3();
  f6();
  f4();
  f5();
  return 0;
}
于 2016-12-03T12:28:12.747 回答
3

time(NULL)函数调用将返回自 epoc:1970 年 1 月 1 日以来经过的秒数。也许您的意思是取两个时间戳之间的差异:

size_t start = time(NULL);
doSomthing();
doSomthingLong();

printf ("**MyProgram::time elapsed= %lds\n", time(NULL) - start);
于 2010-05-11T06:29:25.233 回答
3

C++ std::chrono 具有跨平台的明显优势。但是,与 POSIX clock_gettime() 相比,它也引入了显着的开销。在我的 Linux 机器上,所有std::chrono::xxx_clock::now()版本的性能大致相同:

std::chrono::system_clock::now()
std::chrono::steady_clock::now()
std::chrono::high_resolution_clock::now()

虽然 POSIXclock_gettime(CLOCK_MONOTONIC, &time)应该是一样的,steady_clock::now()但它比它快 3 倍以上!

为了完整起见,这是我的测试。

#include <stdio.h>
#include <chrono>
#include <ctime>

void print_timediff(const char* prefix, const struct timespec& start, const 
struct timespec& end)
{
    double milliseconds = end.tv_nsec >= start.tv_nsec
                        ? (end.tv_nsec - start.tv_nsec) / 1e6 + (end.tv_sec - start.tv_sec) * 1e3
                        : (start.tv_nsec - end.tv_nsec) / 1e6 + (end.tv_sec - start.tv_sec - 1) * 1e3;
    printf("%s: %lf milliseconds\n", prefix, milliseconds);
}

int main()
{
    int i, n = 1000000;
    struct timespec start, end;

    // Test stopwatch
    clock_gettime(CLOCK_MONOTONIC, &start);
    for (i = 0; i < n; ++i) {
        struct timespec dummy;
        clock_gettime(CLOCK_MONOTONIC, &dummy);
    }
    clock_gettime(CLOCK_MONOTONIC, &end);
    print_timediff("clock_gettime", start, end);

    // Test chrono system_clock
    clock_gettime(CLOCK_MONOTONIC, &start);
    for (i = 0; i < n; ++i)
        auto dummy = std::chrono::system_clock::now();
    clock_gettime(CLOCK_MONOTONIC, &end);
    print_timediff("chrono::system_clock::now", start, end);

    // Test chrono steady_clock
    clock_gettime(CLOCK_MONOTONIC, &start);
    for (i = 0; i < n; ++i)
        auto dummy = std::chrono::steady_clock::now();
    clock_gettime(CLOCK_MONOTONIC, &end);
    print_timediff("chrono::steady_clock::now", start, end);

    // Test chrono high_resolution_clock
    clock_gettime(CLOCK_MONOTONIC, &start);
    for (i = 0; i < n; ++i)
        auto dummy = std::chrono::high_resolution_clock::now();
    clock_gettime(CLOCK_MONOTONIC, &end);
    print_timediff("chrono::high_resolution_clock::now", start, end);

    return 0;
}

这是我用 gcc7.2 -O3 编译时得到的输出:

clock_gettime: 24.484926 milliseconds
chrono::system_clock::now: 85.142108 milliseconds
chrono::steady_clock::now: 87.295347 milliseconds
chrono::high_resolution_clock::now: 84.437838 milliseconds
于 2018-03-12T13:02:58.803 回答
3

正如其他人已经指出的那样,C 标准库中的 time() 函数的分辨率不超过一秒。唯一可以提供更好分辨率的完全可移植的 C 函数似乎是 clock(),但它测量的是处理器时间而不是挂钟时间。如果一个人满足于将自己限制在 POSIX 平台(例如 Linux),那么 clock_gettime() 函数是一个不错的选择。

自 C++11 以来,有更好的计时工具可用,以一种可以在不同编译器和操作系统之间非常可移植的形式提供更好的分辨率。类似地, boost::datetime 库提供了良好的高分辨率时序类,应该是高度可移植的。

使用任何这些工具的一个挑战是通过查询系统时钟引入的时间延迟。通过对clock_gettime()、boost::datetime和std::chrono 的试验,这种延迟很容易达到微秒级。因此,在测量代码的任何部分的持续时间时,您需要允许存在大约此大小的测量误差,或者尝试以某种方式纠正该零误差。理想情况下,您可能希望收集函数所用时间的多个测量值,并计算多次运行所用时间的平均值或最大/最小时间。

为了帮助解决所有这些可移植性和统计数据收集问题,我一直在开发Github上的 cxx-rtimers 库,它试图为 C++ 代码的计时块、计算零错误和报告来自多个嵌入式计时器的统计数据提供一个简单的 API在你的代码中。如果你有一个 C++11 编译器,你只需#include <rtimers/cxx11.hpp>, 并使用类似的东西:

void expensiveFunction() {
    static rtimers::cxx11::DefaultTimer timer("expensiveFunc");
    auto scopedStartStop = timer.scopedStart();
    // Do something costly...
}

在程序退出时,您将获得写入 std::cerr 的时序统计摘要,例如:

Timer(expensiveFunc): <t> = 6.65289us, std = 3.91685us, 3.842us <= t <= 63.257us (n=731)

它显示了平均时间、标准偏差、上限和下限以及调用此函数的次数。

如果你想使用 Linux 特定的计时函数,你可以#include <rtimers/posix.hpp>,或者如果你有 Boost 库但旧的 C++ 编译器,你可以#include <rtimers/boost.hpp>。这些计时器类也有一些版本,可以跨多个线程收集统计计时信息。还有一些方法可以让您估计与系统时钟的两个立即连续查询相关的零误差。

于 2018-02-10T09:07:35.270 回答
3

在 linux 上,clock_gettime() 是不错的选择之一。您必须链接实时库(-lrt)。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>

#define BILLION  1000000000L;

int main( int argc, char **argv )
  {
    struct timespec start, stop;
    double accum;

    if( clock_gettime( CLOCK_REALTIME, &start) == -1 ) {
      perror( "clock gettime" );
      exit( EXIT_FAILURE );
    }

    system( argv[1] );

    if( clock_gettime( CLOCK_REALTIME, &stop) == -1 ) {
      perror( "clock gettime" );
      exit( EXIT_FAILURE );
    }

    accum = ( stop.tv_sec - start.tv_sec )
          + ( stop.tv_nsec - start.tv_nsec )
            / BILLION;
    printf( "%lf\n", accum );
    return( EXIT_SUCCESS );
  }
于 2015-09-22T21:44:32.110 回答
2

在内部,该函数将访问系统的时钟,这就是每次调用它时它返回不同值的原因。通常,对于非函数式语言,函数中可能存在许多副作用和隐藏状态,仅通过查看函数的名称和参数是看不到的。

于 2010-05-11T06:17:18.553 回答
2

从所见, tv_sec 存储经过的秒数,而 tv_usec 分别存储经过的微秒数。他们不是彼此的转换。因此,必须将它们更改为适当的单位并添加以获得总时间。

struct timeval startTV, endTV;

gettimeofday(&startTV, NULL); 

doSomething();
doSomethingLong();

gettimeofday(&endTV, NULL); 

printf("**time taken in microseconds = %ld\n",
    (endTV.tv_sec * 1e6 + endTV.tv_usec - (startTV.tv_sec * 1e6 + startTV.tv_usec))
    );
于 2015-01-26T09:50:30.033 回答
2

我需要测量库中各个函数的执行时间。我不想用时间测量函数来包装每个函数的每个调用,因为它丑陋并加深了调用堆栈。我也不想将计时器代码放在每个函数的顶部和底部,因为当函数可以提前退出或抛出异常时,它会造成混乱。所以我最终做的是制作一个使用自己的生命周期来测量时间的计时器。

通过这种方式,我可以通过在相关代码块的开头实例化其中一个对象(实际上是函数或任何范围)然后允许实例析构函数测量自实例超出范围时的构造。您可以在此处找到完整示例,但结构非常简单:

template <typename clock_t = std::chrono::steady_clock>
struct scoped_timer {
  using duration_t = typename clock_t::duration;
  const std::function<void(const duration_t&)> callback;
  const std::chrono::time_point<clock_t> start;

  scoped_timer(const std::function<void(const duration_t&)>& finished_callback) :
      callback(finished_callback), start(clock_t::now()) { }
  scoped_timer(std::function<void(const duration_t&)>&& finished_callback) :
      callback(finished_callback), start(clock_t::now()) { }
  ~scoped_timer() { callback(clock_t::now() - start); }
};

当它超出范围时,该结构将在提供的仿函数上回调您,以便您可以对时间信息做一些事情(打印或存储它或其他)。如果你需要做一些更复杂的事情,你甚至可以使用std::bindwithstd::placeholders来回调具有更多参数的函数。

这是一个使用它的简单示例:

void test(bool should_throw) {
  scoped_timer<> t([](const scoped_timer<>::duration_t& elapsed) {
    auto e = std::chrono::duration_cast<std::chrono::duration<double, std::milli>>(elapsed).count();
    std::cout << "took " << e << "ms" << std::endl;
  });

  std::this_thread::sleep_for(std::chrono::seconds(1));

  if (should_throw)
    throw nullptr;

  std::this_thread::sleep_for(std::chrono::seconds(1));
}

如果您想更加慎重,您还可以使用newanddelete来显式启动和停止计时器,而无需依赖范围来为您执行此操作。

于 2019-03-20T16:21:18.497 回答
1

The reason both values are the same is because your long procedure doesn't take that long - less than one second. You can try just adding a long loop (for (int i = 0; i < 100000000; i++) ; ) at the end of the function to make sure this is the issue, then we can go from there...

In case the above turns out to be true, you will need to find a different system function (I understand you work on linux, so I can't help you with the function name) to measure time more accurately. I am sure there is a function simular to GetTickCount() in linux, you just need to find it.

于 2010-05-11T06:35:59.640 回答
1

它们是相同的,因为您的 doSomething 函数比计时器的粒度发生得更快。尝试:

printf ("**MyProgram::before time= %ld\n", time(NULL));

for(i = 0; i < 1000; ++i) {
    doSomthing();
    doSomthingLong();
}

printf ("**MyProgram::after time= %ld\n", time(NULL));
于 2010-05-11T06:28:07.970 回答
1

Matlab调味!

tic启动秒表计时器以测量性能。该函数记录执行 tic 命令时的内部时间。toc使用该功能显示经过的时间。

#include <iostream>
#include <ctime>
#include <thread>
using namespace std;

clock_t START_TIMER;

clock_t tic()
{
    return START_TIMER = clock();
}

void toc(clock_t start = START_TIMER)
{
    cout
        << "Elapsed time: "
        << (clock() - start) / (double)CLOCKS_PER_SEC << "s"
        << endl;
}

int main()
{
    tic();
    this_thread::sleep_for(2s);
    toc();

    return 0;
}
于 2020-03-02T19:25:58.377 回答
1

我通常使用以下内容:

#include <chrono>
#include <type_traits>

using perf_clock = std::conditional<
    std::chrono::high_resolution_clock::is_steady,
    std::chrono::high_resolution_clock,
    std::chrono::steady_clock
>::type;

using floating_seconds = std::chrono::duration<double>;

template<class F, class... Args>
floating_seconds run_test(Func&& func, Args&&... args)
{
   const auto t0 = perf_clock::now();
   std::forward<Func>(func)(std::forward<Args>(args)...);
   return floating_seconds(perf_clock::now() - t0);
} 

这与@nikos-athanasiou 提出的相同,只是我避免使用非稳定时钟并使用浮点数作为持续时间。

于 2016-02-15T11:52:41.880 回答
0

回答OP的三个具体问题。

“我不明白的是,为什么前后的值是一样的?

一个问题和示例代码显示time()分辨率为 1 秒,因此答案必须是两个函数在不到 1 秒内执行。有时它会(显然不合逻辑地)通知1 秒,如果两个计时器标记跨越一秒边界。

下一个示例使用gettimeofday()填充此结构

struct timeval {
    time_t      tv_sec;     /* seconds */
    suseconds_t tv_usec;    /* microseconds */
};

第二个问题是:“我如何读取 的结果**time taken = 0 26339?这是否意味着 26,339 纳秒 = 26.3 毫秒?”

我的第二个答案是所花费的时间是 0 秒和 26339 微秒,即 0.026339 秒,这证明了第一个示例在不到 1 秒内执行。

第三个问题是:**time taken = 4 45025那是 4 秒 25 毫秒吗?”

我的第三个回答是耗时4秒45025微秒,也就是4.045025秒,说明OP改变了他之前定时的两个函数执行的任务。

于 2015-01-26T20:27:07.733 回答
-1

我创建了一个类来自动测量经过的时间,请检查此链接中的代码(c++11):https ://github.com/sonnt174/Common/blob/master/time_measure.h

如何使用 TimeMeasure 类的示例:

void test_time_measure(std::vector<int> arr) {
  TimeMeasure<chrono::microseconds> time_mea;  // create time measure obj
  std::sort(begin(arr), end(arr));
}
于 2020-01-18T17:12:48.567 回答
-1
#include <ctime>
#include <functional>

using namespace std;

void f() {
  clock_t begin = clock();

  // ...code to measure time...

  clock_t end = clock();

  function<double(double, double)> convtime = [](clock_t begin, clock_t end)
  {
     return double(end - begin) / CLOCKS_PER_SEC;
  };

  printf("Elapsed time: %.2g sec\n", convtime(begin, end));

}

与此处可用的示例类似,仅具有附加转换功能+打印输出。

于 2019-10-24T06:32:20.857 回答