axgn123
发布于 2026-07-03 / 0 阅读
0
0

c++和python之间性能差距的一点感悟

今天在了解到了strace这个工具,然后就想着用它来看看c++和python之间的性能差距,于是就写了一个简单的程序,然后用strace来查看系统调用的次数,结果发现c++的程序调用次数要远远少于python的程序。

用来测试的c++代码如下:

#include <iostream>

int main(int argc, const char** argv) {
  std::cout << "hello world\n";
  return 0;
}

用来测试的python代码如下:

print("hello world\n")

然后用strace来查看系统调用的次数:

strace -c ./a.out
strace -c python3 test.py

结果如下:


# c++
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 33.10    0.000239           4        58        53 openat
 22.30    0.000161           7        22           mmap
  9.70    0.000070           8         8           mprotect
  5.96    0.000043          21         2           write
  4.57    0.000033          33         1           prlimit64
  4.29    0.000031           1        16         9 newfstatat
  3.74    0.000027           5         5           close
  3.19    0.000023           5         4           read
  2.77    0.000020          20         1           munmap
  2.63    0.000019           6         3           brk
  1.94    0.000014          14         1           getrandom
  1.39    0.000010          10         1           futex
  1.11    0.000008           4         2         1 arch_prctl
  1.11    0.000008           8         1           set_tid_address
  1.11    0.000008           8         1           set_robust_list
  1.11    0.000008           8         1           rseq
  0.00    0.000000           0         4           pread64
  0.00    0.000000           0         1         1 access
  0.00    0.000000           0         1           execve
------ ----------- ----------- --------- --------- ----------------
100.00    0.000722           5       133        64 total

# python
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 34.89    0.002077           8       248        38 newfstatat
 19.52    0.001162          15        77           read
 12.78    0.000761           6       110        56 openat
 10.13    0.000603          25        24           getdents64
  7.91    0.000471           6        74         3 lseek
  6.11    0.000364           6        57           close
  4.87    0.000290           6        46        39 ioctl
  0.79    0.000047          23         2           write
  0.79    0.000047           1        28           mmap
  0.57    0.000034           3        10           brk
  0.42    0.000025          12         2           munmap
  0.29    0.000017           3         5         3 readlink
  0.17    0.000010          10         1           getuid
  0.15    0.000009           0        66           rt_sigaction
  0.15    0.000009           4         2           getcwd
  0.15    0.000009           9         1           getgid
  0.15    0.000009           9         1           geteuid
  0.15    0.000009           9         1           getegid
  0.00    0.000000           0         9           mprotect
  0.00    0.000000           0         4           pread64
  0.00    0.000000           0         1         1 access
  0.00    0.000000           0         3           dup
  0.00    0.000000           0         1           execve
  0.00    0.000000           0         1           fcntl
  0.00    0.000000           0         1           sysinfo
  0.00    0.000000           0         2         1 arch_prctl
  0.00    0.000000           0         1           futex
  0.00    0.000000           0         1           set_tid_address
  0.00    0.000000           0         1           set_robust_list
  0.00    0.000000           0         1           prlimit64
  0.00    0.000000           0         2           getrandom
  0.00    0.000000           0         1           rseq
------ ----------- ----------- --------- --------- ----------------
100.00    0.005953           7       784       141 total

可以看到c++总共进行了133次系统调用,而python总共进行了784次系统调用,而且还可以看到c++系统调用的时间总共只有0.000722s,而python却花了0.005953秒,这也就说明了c++的性能要远远好于python。这也就是为什么很多大型的项目都是用c++来写的原因吧。同时我还了解到可以通过ltrace来查看动态库函数调用的执行次数,所以我也尝试了一下,使用ltrace,ltrace可以通过apt-get install ltrace直接安装,与strace的使用方法基本一致,测试结果如下:


# c++
% time     seconds  usecs/call     calls      function
------ ----------- ----------- --------- --------------------
 68.45    0.001506        1506         1 _ZNSt8ios_base4InitC1Ev
 21.73    0.000478         478         1 _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
  6.55    0.000144         144         1 _ZNSolsEPFRSoS_E
  3.27    0.000072          72         1 __cxa_atexit
------ ----------- ----------- --------- --------------------
100.00    0.002200                     4 total

# python
% time     seconds  usecs/call     calls      function
------ ----------- ----------- --------- --------------------
 23.47    1.515623          65     22992 memcpy
 12.93    0.834656          67     12446 strlen
 11.38    0.735042          66     11101 memset
  9.39    0.606523          65      9291 memcmp
  7.88    0.508997          69      7289 pthread_mutex_lock
  7.87    0.508476          69      7289 pthread_mutex_unlock
  5.23    0.337681          69      4859 pthread_cond_signal
  2.95    0.190305          63      3019 wcstombs
  2.82    0.182225          70      2598 __errno_location
  2.20    0.142134          71      1980 readdir64
  1.82    0.117427        1726        68 read
  1.15    0.074294         495       150 stat64
  1.09    0.070605          65      1074 pthread_self
  0.98    0.063064          70       893 strncmp
  0.91    0.059068       19689         3 qsort
  0.89    0.057308          69       820 strcmp
  0.83    0.053327          65       808 strchr
  0.74    0.047969          64       748 mbstowcs
  0.71    0.045808          63       721 wcscmp
  0.54    0.034866          64       539 sem_post
  0.54    0.034743        1052        33 open64
  0.43    0.027669          87       315 strrchr
  0.42    0.027413          67       408 sem_trywait
  0.39    0.025498          66       386 memmove
  0.30    0.019511          71       271 __ctype_b_loc
  0.29    0.018577          66       278 realloc
  0.26    0.016521          67       246 wcslen
  0.14    0.009171          70       131 sem_wait
  0.14    0.008875         125        71 lseek64
  0.13    0.008263          66       125 sem_destroy
  0.13    0.008143          65       125 sem_init
  0.12    0.008060         122        66 fstat64
  0.12    0.007463         109        68 sigaction
  0.11    0.007193        1798         4 fopen64
  0.11    0.006882          69        99 memrchr
  0.08    0.005425         120        45 isatty
  0.07    0.004799         133        36 close
  0.05    0.003121          74        42 wcscat
  0.04    0.002873          95        30 getenv
  0.04    0.002311          77        30 memchr
  0.03    0.002087         173        12 opendir
  0.02    0.001526         127        12 closedir
  0.02    0.001500          68        22 strerror
  0.02    0.001443          84        17 calloc
  0.02    0.001408          78        18 wcscpy
  0.02    0.001079         119         9 setlocale
  0.01    0.000751          57        13 wcschr
  0.01    0.000714          71        10 __wcsncpy_chk
  0.01    0.000673          67        10 fileno
  0.01    0.000645         322         2 localtime_r
  0.01    0.000449          64         7 nl_langinfo
  0.01    0.000433         108         4 readlink
  0.01    0.000385         385         1 pthread_condattr_init
  0.01    0.000385         128         3 mmap64
  0.01    0.000348         348         1 __realpath_chk
  0.01    0.000325         108         3 dup
  0.00    0.000285         142         2 write
  0.00    0.000254          84         3 __uflow
  0.00    0.000230          57         4 sigemptyset
  0.00    0.000221          73         3 flockfile
  0.00    0.000197          65         3 strncpy
  0.00    0.000193          64         3 funlockfile
  0.00    0.000191          63         3 sysconf
  0.00    0.000189          94         2 __vsnprintf_chk
  0.00    0.000178         178         1 fread
  0.00    0.000169         169         1 getcwd
  0.00    0.000164          82         2 strcpy
  0.00    0.000159         159         1 pthread_condattr_setclock
  0.00    0.000150          75         2 fflush
  0.00    0.000140         140         1 ftell
  0.00    0.000136         136         1 getrandom
  0.00    0.000133         133         1 ioctl
  0.00    0.000133         133         1 fclose
  0.00    0.000132         132         1 getc
  0.00    0.000119          59         2 pthread_mutex_init
  0.00    0.000119         119         1 rewind
  0.00    0.000114          57         2 pthread_cond_init
  0.00    0.000107         107         1 getuid
  0.00    0.000105         105         1 getegid
  0.00    0.000104         104         1 getgid
  0.00    0.000101         101         1 geteuid
  0.00    0.000098          98         1 fcntl64
  0.00    0.000089          89         1 __sprintf_chk
  0.00    0.000087          87         1 pthread_key_delete
  0.00    0.000086          86         1 pthread_key_create
  0.00    0.000079          79         1 ungetc
  0.00    0.000068          68         1 wcsrchr
  0.00    0.000067          67         1 confstr
  0.00    0.000064          64         1 floor
  0.00    0.000063          63         1 time
  0.00    0.000060          60         1 __libc_current_sigrtmin
  0.00    0.000058          58         1 getauxval
  0.00    0.000058          58         1 __libc_current_sigrtmax
  0.00    0.000056          56         1 pthread_setspecific
  0.00    0.000056          56         1 pthread_getspecific
------ ----------- ----------- --------- --------------------
100.00    6.457072                 91699 total

可以看到c++总共进行了4次动态库函数调用,而python却进行了91699次动态库函数调用,我有点惊讶,没想到python动态库函数调用的次数会这么多,而c++却只有四次,在时间方面,c++只用了0.002200秒,而python却用了6.457072秒,两者差距非常大。不过python如果只是单纯地打印hello world的话,应该是用不到一秒的啊,(或许这里的动态库函数调用应该也包括了ltrace跟踪函数调用所需要调用的函数吧。)


评论