性能测试的意义

在做完一个python项目之后,我们经常要考虑对软件的性能进行优化。那么我们需要一个软件优化的思路,首先我们需要明确软件本身代码以及函数的瓶颈,最理想的情况就是有这样一个工具,能够将一个目标函数的代码每一行的性能都评估出来,这样我们可以针对所有代码中性能最差的那一部分,来进行针对性的优化。开源库line_profiler就做了一个这样的工作,开源地址:github.com/rkern/line_profiler。下面让我们一起看下该工具的安装和使用详情。

line_profiler的安装

line_profiler的安装支持源码安装和pip的安装,这里我们仅介绍pip形式的安装,也比较容易,源码安装方式请参考官方开源地址。

  1. [dechin@dechin-manjaro line_profiler]$ python3 -m pip install line_profiler
  2. Collecting line_profiler
  3. Downloading line_profiler-3.1.0-cp38-cp38-manylinux2010_x86_64.whl (65 kB)
  4. |████████████████████████████████| 65 kB 221 kB/s
  5. Requirement already satisfied: IPython in /home/dechin/anaconda3/lib/python3.8/site-packages (from line_profiler) (7.19.0)
  6. Requirement already satisfied: prompt-toolkit!=3.0.0,!=3.0.1,<3.1.0,>=2.0.0 in /home/dechin/anaconda3/lib/python3.8/site-packages (from IPython->line_profiler) (3.0.8)
  7. Requirement already satisfied: backcall in /home/dechin/anaconda3/lib/python3.8/site-packages (from IPython->line_profiler) (0.2.0)
  8. Requirement already satisfied: pexpect>4.3; sys_platform != "win32" in /home/dechin/anaconda3/lib/python3.8/site-packages (from IPython->line_profiler) (4.8.0)
  9. Requirement already satisfied: setuptools>=18.5 in /home/dechin/anaconda3/lib/python3.8/site-packages (from IPython->line_profiler) (50.3.1.post20201107)
  10. Requirement already satisfied: jedi>=0.10 in /home/dechin/anaconda3/lib/python3.8/site-packages (from IPython->line_profiler) (0.17.1)
  11. Requirement already satisfied: decorator in /home/dechin/anaconda3/lib/python3.8/site-packages (from IPython->line_profiler) (4.4.2)
  12. Requirement already satisfied: traitlets>=4.2 in /home/dechin/anaconda3/lib/python3.8/site-packages (from IPython->line_profiler) (5.0.5)
  13. Requirement already satisfied: pygments in /home/dechin/anaconda3/lib/python3.8/site-packages (from IPython->line_profiler) (2.7.2)
  14. Requirement already satisfied: pickleshare in /home/dechin/anaconda3/lib/python3.8/site-packages (from IPython->line_profiler) (0.7.5)
  15. Requirement already satisfied: wcwidth in /home/dechin/anaconda3/lib/python3.8/site-packages (from prompt-toolkit!=3.0.0,!=3.0.1,<3.1.0,>=2.0.0->IPython->line_profiler) (0.2.5)
  16. Requirement already satisfied: ptyprocess>=0.5 in /home/dechin/anaconda3/lib/python3.8/site-packages (from pexpect>4.3; sys_platform != "win32"->IPython->line_profiler) (0.6.0)
  17. Requirement already satisfied: parso<0.8.0,>=0.7.0 in /home/dechin/anaconda3/lib/python3.8/site-packages (from jedi>=0.10->IPython->line_profiler) (0.7.0)
  18. Requirement already satisfied: ipython-genutils in /home/dechin/anaconda3/lib/python3.8/site-packages (from traitlets>=4.2->IPython->line_profiler) (0.2.0)
  19. Installing collected packages: line-profiler
  20. Successfully installed line-profiler-3.1.0

这里额外介绍一种临时使用pip的源进行安装的方案,这里用到的是腾讯所提供的pypi源:

  1. python3 -m pip install -i https://mirrors.cloud.tencent.com/pypi/simple line_profiler

如果需要永久保存源可以修改~/.pip/pip.conf文件,一个参考示例如下(采用华为云的镜像源):

  1. [global]
  2. index-url = https://mirrors.huaweicloud.com/repository/pypi/simple
  3. trusted-host = mirrors.huaweicloud.com
  4. timeout = 120

在需要调试优化的代码中引用line_profiler

让我们直接来看一个案例:

  1. # line_profiler_test.py
  2. from line_profiler import LineProfiler
  3. import numpy as np
  4. @profile
  5. def test_profiler():
  6. for i in range(100):
  7. a = np.random.randn(100)
  8. b = np.random.randn(1000)
  9. c = np.random.randn(10000)
  10. return None
  11. if __name__ == '__main__':
  12. test_profiler()

在这个案例中,我们定义了一个需要测试的函数test_profiler,在这个函数中有几行待分析性能的模块numpy.random.randn。使用的方式就是先import进来LineProfiler函数,然后在需要逐行进行性能分析的函数上方引用名为profile的装饰器,就完成了line_profiler性能分析的配置。关于python装饰器的使用和原理,可以参考这篇博客的内容介绍。还有一点需要注意的是,line_profiler所能够分析的范围仅限于加了装饰器的函数内容,如果函数内有其他的调用之类的,不会再进入其他的函数进行分析,除了内嵌的嵌套函数。

使用line_profiler进行简单性能分析

line_profiler的使用方法也较为简单,主要就是两步:先用kernprof解析,再采用python执行得到分析结果。

  1. 在定义好需要分析的函数模块之后,用kernprof解析成二进制lprof文件:
  1. [dechin-manjaro line_profiler]# kernprof -l line_profiler_test.py
  2. Wrote profile results to line_profiler_test.py.lprof

该命令执行结束后,会在当前目录下产生一个lprof文件:

  1. [dechin-manjaro line_profiler]# ll
  2. 总用量 8
  3. -rw-r--r-- 1 dechin dechin 304 1 20 16:00 line_profiler_test.py
  4. -rw-r--r-- 1 root root 185 1 20 16:00 line_profiler_test.py.lprof
  1. 使用python3运行lprof二进制文件:
  1. [dechin-manjaro line_profiler]# python3 -m line_profiler line_profiler_test.py.lprof
  2. Timer unit: 1e-06 s
  3. Total time: 0.022633 s
  4. File: line_profiler_test.py
  5. Function: test_profiler at line 5
  6. Line # Hits Time Per Hit % Time Line Contents
  7. ==============================================================
  8. 5 @profile
  9. 6 def test_profiler():
  10. 7 101 40.0 0.4 0.2 for i in range(100):
  11. 8 100 332.0 3.3 1.5 a = np.random.randn(100)
  12. 9 100 2092.0 20.9 9.2 b = np.random.randn(1000)
  13. 10 100 20169.0 201.7 89.1 c = np.random.randn(10000)
  14. 11 1 0.0 0.0 0.0 return None

这里我们就直接得到了逐行的性能分析结论。简单介绍一下每一列的含义:代码在代码文件中对应的行号、被调用的次数、该行的总共执行时间、单次执行所消耗的时间、执行时间在该函数下的占比,最后一列是具体的代码内容。其实,关于line_profiler的使用介绍到这里就可以结束了,但是我们希望通过另外一个实际案例来分析line_profiler的功能,感兴趣的读者可以继续往下阅读。

使用line_profiler分析不同函数库计算正弦函数sin的效率

我们这里需要测试多个库中所实现的正弦函数,其中包含我们自己使用的fortran内置的SIN函数。

在演示line_profiler的性能测试之前,让我们先看看如何将一个fortran的f90文件转换成python可调用的动态链接库文件。

  1. 首先在Manjaro Linux平台上安装gfotran
  1. [dechin-manjaro line_profiler]# pacman -S gcc-fortran
  2. 正在解析依赖关系...
  3. 正在查找软件包冲突...
  4. 软件包 (1) gcc-fortran-10.2.0-4
  5. 下载大小: 9.44 MiB
  6. 全部安装大小: 31.01 MiB
  7. :: 进行安装吗? [Y/n] Y
  8. :: 正在获取软件包......
  9. gcc-fortran-10.2.0-4-x86_64 9.4 MiB 6.70 MiB/s 00:01 [#######################################################################################] 100%
  10. (1/1) 正在检查密钥环里的密钥 [#######################################################################################] 100%
  11. (1/1) 正在检查软件包完整性 [#######################################################################################] 100%
  12. (1/1) 正在加载软件包文件 [#######################################################################################] 100%
  13. (1/1) 正在检查文件冲突 [#######################################################################################] 100%
  14. (1/1) 正在检查可用存储空间 [#######################################################################################] 100%
  15. :: 正在处理软件包的变化...
  16. (1/1) 正在安装 gcc-fortran [#######################################################################################] 100%
  17. :: 正在运行事务后钩子函数...
  18. (1/2) Arming ConditionNeedsUpdate...
  19. (2/2) Updating the info directory file...
  1. 创建一个简单的fortran文件fmath.f90,功能为返回正弦函数的值:
  1. subroutine fsin(theta,result)
  2. implicit none
  3. real*8::theta
  4. real*8,intent(out)::result
  5. result=SIN(theta)
  6. end subroutine
  1. 用f2py将该fortran文件编译成名为fmath的动态链接库:
  1. [dechin-manjaro line_profiler]# f2py -c -m fmath fmath.f90
  2. running build
  3. running config_cc
  4. unifing config_cc, config, build_clib, build_ext, build commands --compiler options
  5. running config_fc
  6. unifing config_fc, config, build_clib, build_ext, build commands --fcompiler options
  7. running build_src
  8. build_src
  9. building extension "fmath" sources
  10. f2py options: []
  11. f2py:> /tmp/tmpup5ia9lf/src.linux-x86_64-3.8/fmathmodule.c
  12. creating /tmp/tmpup5ia9lf/src.linux-x86_64-3.8
  13. Reading fortran codes...
  14. Reading file 'fmath.f90' (format:free)
  15. Post-processing...
  16. Block: fmath
  17. Block: fsin
  18. Post-processing (stage 2)...
  19. Building modules...
  20. Building module "fmath"...
  21. Constructing wrapper function "fsin"...
  22. result = fsin(theta)
  23. Wrote C/API module "fmath" to file "/tmp/tmpup5ia9lf/src.linux-x86_64-3.8/fmathmodule.c"
  24. adding '/tmp/tmpup5ia9lf/src.linux-x86_64-3.8/fortranobject.c' to sources.
  25. adding '/tmp/tmpup5ia9lf/src.linux-x86_64-3.8' to include_dirs.
  26. copying /home/dechin/anaconda3/lib/python3.8/site-packages/numpy/f2py/src/fortranobject.c -> /tmp/tmpup5ia9lf/src.linux-x86_64-3.8
  27. copying /home/dechin/anaconda3/lib/python3.8/site-packages/numpy/f2py/src/fortranobject.h -> /tmp/tmpup5ia9lf/src.linux-x86_64-3.8
  28. build_src: building npy-pkg config files
  29. running build_ext
  30. customize UnixCCompiler
  31. customize UnixCCompiler using build_ext
  32. get_default_fcompiler: matching types: '['gnu95', 'intel', 'lahey', 'pg', 'absoft', 'nag', 'vast', 'compaq', 'intele', 'intelem', 'gnu', 'g95', 'pathf95', 'nagfor']'
  33. customize Gnu95FCompiler
  34. Found executable /usr/bin/gfortran
  35. customize Gnu95FCompiler
  36. customize Gnu95FCompiler using build_ext
  37. building 'fmath' extension
  38. compiling C sources
  39. C compiler: gcc -pthread -B /home/dechin/anaconda3/compiler_compat -Wl,--sysroot=/ -Wsign-compare -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -fPIC
  40. creating /tmp/tmpup5ia9lf/tmp
  41. creating /tmp/tmpup5ia9lf/tmp/tmpup5ia9lf
  42. creating /tmp/tmpup5ia9lf/tmp/tmpup5ia9lf/src.linux-x86_64-3.8
  43. compile options: '-I/tmp/tmpup5ia9lf/src.linux-x86_64-3.8 -I/home/dechin/anaconda3/lib/python3.8/site-packages/numpy/core/include -I/home/dechin/anaconda3/include/python3.8 -c'
  44. gcc: /tmp/tmpup5ia9lf/src.linux-x86_64-3.8/fmathmodule.c
  45. gcc: /tmp/tmpup5ia9lf/src.linux-x86_64-3.8/fortranobject.c
  46. In file included from /home/dechin/anaconda3/lib/python3.8/site-packages/numpy/core/include/numpy/ndarraytypes.h:1822,
  47. from /home/dechin/anaconda3/lib/python3.8/site-packages/numpy/core/include/numpy/ndarrayobject.h:12,
  48. from /home/dechin/anaconda3/lib/python3.8/site-packages/numpy/core/include/numpy/arrayobject.h:4,
  49. from /tmp/tmpup5ia9lf/src.linux-x86_64-3.8/fortranobject.h:13,
  50. from /tmp/tmpup5ia9lf/src.linux-x86_64-3.8/fmathmodule.c:15:
  51. /home/dechin/anaconda3/lib/python3.8/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:17:2: 警告:#warning "Using deprecated NumPy API, disable it with " "#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-Wcpp]
  52. 17 | #warning "Using deprecated NumPy API, disable it with " \
  53. | ^~~~~~~
  54. In file included from /home/dechin/anaconda3/lib/python3.8/site-packages/numpy/core/include/numpy/ndarraytypes.h:1822,
  55. from /home/dechin/anaconda3/lib/python3.8/site-packages/numpy/core/include/numpy/ndarrayobject.h:12,
  56. from /home/dechin/anaconda3/lib/python3.8/site-packages/numpy/core/include/numpy/arrayobject.h:4,
  57. from /tmp/tmpup5ia9lf/src.linux-x86_64-3.8/fortranobject.h:13,
  58. from /tmp/tmpup5ia9lf/src.linux-x86_64-3.8/fortranobject.c:2:
  59. /home/dechin/anaconda3/lib/python3.8/site-packages/numpy/core/include/numpy/npy_1_7_deprecated_api.h:17:2: 警告:#warning "Using deprecated NumPy API, disable it with " "#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION" [-Wcpp]
  60. 17 | #warning "Using deprecated NumPy API, disable it with " \
  61. | ^~~~~~~
  62. compiling Fortran sources
  63. Fortran f77 compiler: /usr/bin/gfortran -Wall -g -ffixed-form -fno-second-underscore -fPIC -O3 -funroll-loops
  64. Fortran f90 compiler: /usr/bin/gfortran -Wall -g -fno-second-underscore -fPIC -O3 -funroll-loops
  65. Fortran fix compiler: /usr/bin/gfortran -Wall -g -ffixed-form -fno-second-underscore -Wall -g -fno-second-underscore -fPIC -O3 -funroll-loops
  66. compile options: '-I/tmp/tmpup5ia9lf/src.linux-x86_64-3.8 -I/home/dechin/anaconda3/lib/python3.8/site-packages/numpy/core/include -I/home/dechin/anaconda3/include/python3.8 -c'
  67. gfortran:f90: fmath.f90
  68. /usr/bin/gfortran -Wall -g -Wall -g -shared /tmp/tmpup5ia9lf/tmp/tmpup5ia9lf/src.linux-x86_64-3.8/fmathmodule.o /tmp/tmpup5ia9lf/tmp/tmpup5ia9lf/src.linux-x86_64-3.8/fortranobject.o /tmp/tmpup5ia9lf/fmath.o -L/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/../../../../lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/10.2.0/../../../../lib -lgfortran -o ./fmath.cpython-38-x86_64-linux-gnu.so
  69. Removing build directory /tmp/tmpup5ia9lf

这中间会有一些告警,但是并不影响我们的正常使用,编译好之后,可以在当前目录下看到一个so文件(如果是windows平台可能是其他类型的动态链接库文件):

  1. [dechin-manjaro line_profiler]# ll
  2. 总用量 120
  3. -rwxr-xr-x 1 root root 107256 1 20 16:40 fmath.cpython-38-x86_64-linux-gnu.so
  4. -rw-r--r-- 1 root root 150 1 20 16:40 fmath.f90
  5. -rw-r--r-- 1 dechin dechin 304 1 20 16:00 line_profiler_test.py
  6. -rw-r--r-- 1 root root 185 1 20 16:00 line_profiler_test.py.lprof
  1. 用ipython测试该动态链接库的功能是否正常:
  1. [dechin-manjaro line_profiler]# ipython
  2. Python 3.8.5 (default, Sep 4 2020, 07:30:14)
  3. Type 'copyright', 'credits' or 'license' for more information
  4. IPython 7.19.0 -- An enhanced Interactive Python. Type '?' for help.
  5. In [1]: from fmath import fsin
  6. In [2]: print (fsin(3.14))
  7. 0.0015926529164868282
  8. In [3]: print (fsin(3.1415926))
  9. 5.3589793170057245e-08

这里我们可以看到基于fortran的正弦函数的功能已经完成实现了,接下来让我们正式对比几种正弦函数实现的性能(底层的实现有可能重复,这里作为黑盒来进行性能测试)。

首先,我们还是需要创建好待测试的python文件sin_profiler_test.py

  1. # sin_profiler_test.py
  2. from line_profiler import LineProfiler
  3. import random
  4. from numpy import sin as numpy_sin
  5. from math import sin as math_sin
  6. # from cupy import sin as cupy_sin
  7. from cmath import sin as cmath_sin
  8. from fmath import fsin as fortran_sin
  9. @profile
  10. def test_profiler():
  11. for i in range(100000):
  12. r = random.random()
  13. a = numpy_sin(r)
  14. b = math_sin(r)
  15. # c = cupy_sin(r)
  16. d = cmath_sin(r)
  17. e = fortran_sin(r)
  18. return None
  19. if __name__ == '__main__':
  20. test_profiler()

这里line_profiler的定义跟前面定义的例子一致,我们主要测试的对象为numpy,math,cmath四个开源库的正弦函数实现以及自己实现的一个fortran的正弦函数,通过上面介绍的f2py构造的动态链接库跟python实现无缝对接。由于这里的cupy库没有安装成功,所以这里暂时没办法测试而注释掉了。接下来还是一样的,通过kernprof进行编译构建:

  1. [dechin-manjaro line_profiler]# kernprof -l sin_profiler_test.py
  2. Wrote profile results to sin_profiler_test.py.lprof

最后通过python3来执行:

  1. [dechin-manjaro line_profiler]# python3 -m line_profiler sin_profiler_test.py.lprof
  2. Timer unit: 1e-06 s
  3. Total time: 0.261304 s
  4. File: sin_profiler_test.py
  5. Function: test_profiler at line 10
  6. Line # Hits Time Per Hit % Time Line Contents
  7. ==============================================================
  8. 10 @profile
  9. 11 def test_profiler():
  10. 12 100001 28032.0 0.3 10.7 for i in range(100000):
  11. 13 100000 33995.0 0.3 13.0 r = random.random()
  12. 14 100000 86870.0 0.9 33.2 a = numpy_sin(r)
  13. 15 100000 33374.0 0.3 12.8 b = math_sin(r)
  14. 16 # c = cupy_sin(r)
  15. 17 100000 40179.0 0.4 15.4 d = cmath_sin(r)
  16. 18 100000 38854.0 0.4 14.9 e = fortran_sin(r)
  17. 19 1 0.0 0.0 0.0 return None

从这个结果上我们可以看出,在这测试的四个库中,math的计算效率是最高的,numpy的计算效率是最低的,而我们自己编写的fortran接口函数甚至都比numpy的实现快了一倍,仅次于math的实现。其实,这里值涉及到了单个函数的性能测试,我们还可以通过ipython中自带的timeit来进行测试:

  1. [dechin-manjaro line_profiler]# ipython
  2. Python 3.8.5 (default, Sep 4 2020, 07:30:14)
  3. Type 'copyright', 'credits' or 'license' for more information
  4. IPython 7.19.0 -- An enhanced Interactive Python. Type '?' for help.
  5. In [1]: from fmath import fsin
  6. In [2]: import random
  7. In [3]: %timeit fsin(random.random())
  8. 145 ns ± 2.38 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
  9. In [4]: from math import sin as math_sin
  10. In [5]: %timeit math_sin(random.random())
  11. 107 ns ± 0.116 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)
  12. In [6]: from numpy import sin as numpy_sin
  13. In [7]: %timeit numpy_sin(random.random())
  14. 611 ns ± 4.28 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
  15. In [8]: from cmath import sin as cmath_sin
  16. In [9]: %timeit cmath_sin(random.random())
  17. 151 ns ± 1.01 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

在这个结果中我们看到排名的趋势依然跟之前的保持一致,但是由于将random模块和计算模块放在一起,在给出的时间数值上有些差异。

总结概要

本文重点介绍了python的一款逐行性能分析的工具line_profiler,通过简单的装饰器的调用就可以分析出程序的性能瓶颈,从而进行针对性的优化。另外,在测试的过程中我们还可以发现,不同形式的正弦三角函数实现,性能是存在差异的,只是在日常使用频率较低的情况下是不感知的。需要了解的是,即使是正弦函数也有很多不同的实现方案,比如各种级数展开,而目前最流行、性能最高的计算方式,其实还是通过查表法。因此,不同的算法实现、不同的语言实现,都会导致完全不一样的结果。就测试情况而言,已知的性能排名为:math<fortran<cmath<numpy从左到右运行时长逐步增加。

版权声明

本文首发链接为:https://www.cnblogs.com/dechinphy/p/line-profiler.html

作者ID:DechinPhy

更多原著文章请参考:https://www.cnblogs.com/dechinphy/

使用line_profiler对python代码性能进行评估优化的更多相关文章

  1. Python 代码性能优化技巧(转)

    原文:Python 代码性能优化技巧 Python 代码优化常见技巧 代码优化能够让程序运行更快,它是在不改变程序运行结果的情况下使得程序的运行效率更高,根据 80/20 原则,实现程序的重构.优化. ...

  2. [转] Python 代码性能优化技巧

    选择了脚本语言就要忍受其速度,这句话在某种程度上说明了 python 作为脚本的一个不足之处,那就是执行效率和性能不够理想,特别是在 performance 较差的机器上,因此有必要进行一定的代码优化 ...

  3. Python代码性能优化技巧

    摘要:代码优化能够让程序运行更快,可以提高程序的执行效率等,对于一名软件开发人员来说,如何优化代码,从哪里入手进行优化?这些都是他们十分关心的问题.本文着重讲了如何优化Python代码,看完一定会让你 ...

  4. Python 代码性能优化技巧

    选择了脚本语言就要忍受其速度,这句话在某种程度上说明了 python 作为脚本的一个不足之处,那就是执行效率和性能不够理想,特别是在 performance 较差的机器上,因此有必要进行一定的代码优化 ...

  5. 有效提升Python代码性能的三个层面

    使用python进入一个熟练的状态之后就会思考提升代码的性能,尤其是python的执行效率还有很大提升空间(委婉的说法).面对提升效率这个话题,python自身提供了很多高性能模块,很多大牛开发出了高 ...

  6. 使用 profile 进行python代码性能分析

    定位程序性能瓶颈 对代码优化的前提是需要了解性能瓶颈在什么地方,程序运行的主要时间是消耗在哪里,对于比较复杂的代码可以借助一些工具来定位,python 内置了丰富的性能分析工具,如 profile,c ...

  7. python 代码性能分析 库

    问题描述 1.Python开发的程序在使用过程中很慢,想确定下是哪段代码比较慢: 2.Python开发的程序在使用过程中占用内存很大,想确定下是哪段代码引起的: 解决方案 使用profile分析分析c ...

  8. Python性能分析与优化PDF高清完整版免费下载|百度云盘

    百度云盘|Python性能分析与优化PDF高清完整版免费下载 提取码:ubjt 内容简介 全面掌握Python代码性能分析和优化方法,消除性能瓶颈,迅速改善程序性能! 对于Python程序员来说,仅仅 ...

  9. 优化Python代码的4种方法

    介绍 作为数据科学家,编写优化的Python代码非常非常重要.杂乱,效率低下的代码即浪费你的时间甚至浪费你项目的钱.经验丰富的数据科学家和专业人员都知道,当我们与客户合作时,杂乱的代码是不可接受的. ...

随机推荐

  1. TLS 协议

    一.背景 参与了一个Sofa-RPC开源项目,认领了TLS的任务,记录下这次宝贵的经历,并感谢章哥的信任以及在整个过程中对我的帮助. 负责的部分不难,主要是使用h2(HTTP 2加密)协议,完成RPC ...

  2. Docker(二):Docker镜像仓库Harbor搭建

    安装docker-compose 因为docker-compose下载容易失败, 所以选择从github下载方式安装. [root@harbor ~]# mv docker-compose-Linux ...

  3. Go加密算法总结

    前言 加密解密在实际开发中应用比较广泛,常用加解密分为:"对称式"."非对称式"和"数字签名". 对称式:对称加密(也叫私钥加密)指加密和解 ...

  4. matplotlib的学习12-Subplot 多合一显示

    import matplotlib.pyplot as plt # matplotlib 是可以组合许多的小图, 放在一张大图里面显示的. 使用到的方法叫作 subplot. plt.figure() ...

  5. matplotlib的学习3-figure图像

    import matplotlib.pyplot as plt import numpy as np # matplotlib 的 figure 就是一个 单独的 figure 小窗口, 小窗口里面还 ...

  6. .NET生态系统掠影

    如果你是一名开发人员,想要进入到.NET的世界,你需要知道都有哪些可能.由于.NET Framework是..NET生态系统中最流行的技术,你可以用它来构建各种各样的应用程序,但是最近,出现了一些新的 ...

  7. Django之DRF-- API限速

    什么场景下需要限制访问频次呢? 1)防爬虫:爬虫可能会在短时间内大量的访问服务接口,增加服务器压力 2)对于需要限制访问频次的接口 具体使用配置如下: 1,settings.py加入配置 REST_F ...

  8. IQueryable的简单封装

    IQueryable的简单封装 前言 前两天在园子上看到一个问题 半年前我也考虑过这些问题,但由于这样那样的问题,没有尝试去解决. 后来公司用上了 abp vnext ,然后有一部分代码可以这样写 p ...

  9. git文件锁定不更新和忽略

    git文件的忽略 新建未提交的文件直接添加.gitignore 提交之后的文件已被git追踪 这时需要清除git缓存 忽略文件 git rm --cached ./src/main/resources ...

  10. vuejs2.0使用Sortable.js实现的拖拽功能( 转)

    文章目录   简介 实现效果 html主要代码 css代码 js代码 简介 在使用vue1.x之前的版本的时候,页面中的拖拽功能,我在项目中是直接用的jquery ui中的sortable.js,只是 ...