博客首发于:www.weeco.tech/32a1d40ac71…
在之前的探究中,我们已经认识到,不同语言之间的执行效率相差很大。所以,就诞生了这么一个想法,把某些bash运维脚本,用C重写一遍以此来提升运维系统的执行效率。
实验环境
虚拟机:host-CPU直通 Linux CentOS 8.5.2111
CPU:Intel(R) Core(TM) i7-10700K CPU @ 3.80GHz
gcc版本:8.5.0-4
bash版本:4.4.20
实验流程
有那么一个bash运维脚本,用于获取并计算内存总量、剩余内存使用量等信息,具体代码如下:
mem_total=`cat /proc/meminfo | grep MemTotal | awk -F" " '{print $2}'`
mem_free=`cat /proc/meminfo | grep MemFree | awk -F" " '{print $2}'`
mem_available=`cat /proc/meminfo | grep MemAvailable| awk -F" " '{print $2}'`
mem_used=`expr ${mem_total} - ${mem_available}`
mem_total=`expr ${mem_total} * 1024`
mem_used=`expr ${mem_used} * 1024`
mem_free=`expr ${mem_free} * 1024`
echo "mem_total:$mem_total, mem_free:$mem_free, mem_available:$mem_available, mem_used:$mem_used"
我们利用ChatGPT,输入如上的代码,并添加一句"将这段bash脚本转换为C语言代码",ChatGPT就会返回我们所需要的C语言代码。
如上内容,转换为C语言代码后的具体内容如下:
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *meminfo;
char line[128];
unsigned long mem_total = 0, mem_free = 0, mem_available = 0, mem_used = 0;
meminfo = fopen("/proc/meminfo", "r");
if (meminfo == NULL) {
printf("Error opening /proc/meminfo\n");
return 1;
}
while (fgets(line, sizeof(line), meminfo)) {
if (sscanf(line, "MemTotal: %lu kB", &mem_total) == 1) {
mem_total *= 1024;
} else if (sscanf(line, "MemFree: %lu kB", &mem_free) == 1) {
mem_free *= 1024;
} else if (sscanf(line, "MemAvailable: %lu kB", &mem_available) == 1) {
mem_used = mem_total - (mem_available * 1024);
mem_available *= 1024;
}
}
fclose(meminfo);
printf("mem_total:%lu, mem_free:%lu, mem_available:%lu, mem_used:%lu\n",
mem_total, mem_free, mem_available, mem_used);
return 0;
}
利用gcc编译器对该代码进行编译,具体编译指令为gcc get_mem_info.c -O3 -o get_mem_info得到可运行的二进制文件。
为了更好地比较两份代码执行时间的差异,通过如下bash脚本进行耗时统计:
start_timestamp=$(date +%s%N)
[linux command]
end_timestamp=$(date +%s%N)
duration=$((($end_timestamp - $start_timestamp)/1000))
echo "duration - $duration"
同时我们统计了计时bash代码自身的耗时,最终的代码执行耗时统计单元代码如下:
start_timestamp=$(date +%s%N)
bash get_mem_info.sh
end_timestamp=$(date +%s%N)
duration=$((($end_timestamp - $start_timestamp)/1000))
echo "bash duration - $duration us"
start_timestamp=$(date +%s%N)
./get_mem_info
end_timestamp=$(date +%s%N)
duration=$((($end_timestamp - $start_timestamp)/1000))
echo "c exe duration - $duration us"
start_timestamp=$(date +%s%N)
end_timestamp=$(date +%s%N)
duration=$((($end_timestamp - $start_timestamp)/1000))
echo "time calc duration - $duration us"
mem_total:16573603840, mem_free:14469136384, mem_available:14795940, mem_used:1422561280
bash duration - 11592 us
mem_total:16573603840, mem_free:14468235264, mem_available:15150473216, mem_used:1423130624
c exe duration - 1179 us
time calc duration - 682 us
即get_mem_info.sh执行耗时约为(11592 - 682)us = 10.910ms,由C语言编译成的二进制文件get_mem_info耗时约为(1179 - 682)us = 0.497ms,两者耗时比超过20倍!用图的形式看两者的差异会更明显。
结论
ChatGPT是个好帮手,利用这个好帮手,通过将运维脚本中大量低效(相比C/C++等编译型语言)的bash和perl脚本转换为C/C++代码,势必会减少运维管理的资源开销,从而提升服务器的计算能效。