当前位置: 首页 > news >正文

C语言性能优化:从基础到高级的全面指南

引言

C 语言以其高效、灵活和功能强大而著称,被广泛应用于系统编程、嵌入式开发、游戏开发等领域。然而,要写出高性能的 C 语言代码,需要对 C 语言的特性和底层硬件有深入的了解。本文将详细介绍 C 语言性能优化的背后技术,并通过具体的代码示例来展示如何实现性能优化。本文分为多个部分,从基本概念和技巧到高级性能优化技术,全面覆盖 C 语言性能优化的各个方面。
在这里插入图片描述

1. 基本概念和技巧
1.1 数据对齐

数据对齐是指数据的内存地址与数据大小的整数倍对齐。大多数现代计算机系统都要求数据对齐,因为对齐的数据访问速度更快。在 C 语言中,可以通过 #pragma pack 指令来设置数据对齐的方式。

#include <stdio.h>
#pragma pack(1) // 设置数据对齐为1字节
struct Example {char a;int b;char c;
};
#pragma pack() // 恢复默认数据对齐方式int main() {struct Example ex;printf("Size of struct: %zu\n", sizeof(ex)); // 输出结构体大小return 0;
}

在上面的代码中,通过设置 #pragma pack(1),将数据对齐方式设置为 1 字节。这样,结构体 Example 中的数据将按照 1 字节对齐,而不是默认的 4 字节对齐。这会导致结构体的大小变小,但可能会降低访问速度。因此,在实际开发中,需要根据具体情况来选择合适的数据对齐方式。

1.2 循环展开

循环展开是一种通过增加每次迭代中执行的操作数来减少循环次数的技术。这可以减少循环的开销,提高代码的执行速度。

#include <stdio.h>void loop_unrolling(int *arr, int n, int value) {int i;for (i = 0; i < n; i += 2) {arr[i] = value;arr[i + 1] = value;}
}int main() {int arr[10];loop_unrolling(arr, 10, 5);for (int i = 0; i < 10; i++) {printf("%d ", arr[i]);}printf("\n");return 0;
}

在上面的代码中,通过将每次迭代中的操作数从 1 增加到 2,将循环次数减少了一半。这样可以减少循环的开销,提高代码的执行速度。但需要注意的是,循环展开会增加代码的大小,因此需要根据具体情况来选择是否使用循环展开。

1.3 函数内联

函数内联是一种通过将函数调用展开为函数体来减少函数调用开销的技术。在 C 语言中,可以通过 inline 关键字来声明内联函数。

#include <stdio.h>inline int add(int a, int b) {return a + b;
}int main() {int result = add(3, 4);printf("Result: %d\n", result);return 0;
}

在上面的代码中,通过将 add 函数声明为内联函数,编译器会将函数调用展开为函数体,从而减少函数调用的开销。但需要注意的是,内联函数会增加代码的大小,因此需要根据具体情况来选择是否使用内联函数。

2. 编译器优化
2.1 编译器选项

编译器提供了多种优化选项,这些选项可以影响编译过程,从而生成更高效的机器代码。以下是一些常用的编译器优化选项。

  • -O0:无优化(默认选项),用于调试。
  • -O1:一级优化,主要包括去除冗余代码、常量折叠等,不会进行复杂的优化。
  • -O2:二级优化,除了包含一级优化的所有内容外,还包括循环展开、指令重排等。
  • -O3:三级优化,在二级优化的基础上,增加更多的优化措施,如自动向量化。
  • -Ofast:允许编译器进行一些可能违反语言标准的优化,通常能提供更高的性能。
  • -march=native:启用针对本机 CPU 架构的优化,使得生成的代码能够更好地利用特定硬件的特性。
gcc -O0 -o compute_O0 compute.c # 无优化版本
gcc -O1 -o compute_O1 compute.c # 一级优化版本
gcc -O2 -o compute_O2 compute.c # 二级优化版本
gcc -O3 -o compute_O3 compute.c # 三级优化版本
gcc -Ofast -o compute_Ofast compute.c # 可能违反标准的优化版本
gcc -march=native -o compute_native compute.c # 针对本地架构优化版本

通过比较不同优化级别的执行时间,可以选择最适合当前程序的优化选项。

2.2 编译器内置函数

现代编译器通常提供一些内置函数,这些函数可以替代标准库函数或手动编写的代码,以提供更好的性能。

  • __builtin_expect:用于分支预测优化。
  • __builtin_prefetch:用于数据预取,以减少缓存未命中的次数。
#include <stdio.h>// 假设我们有一个检查错误码的函数
int error_check(int error_code) {if (error_code == 0) {// 正常情况} else {// 错误处理}
}// 使用 __builtin_expect 优化
int error_check_optimized(int error_code) {if (__builtin_expect(error_code, 0)) {// 错误处理} else {// 正常情况}
}int main() {int result = error_check_optimized(0);return 0;
}

在这个例子中,我们假设 error_code 很可能为 0,那么这个分支就不太可能被执行。通过使用 __builtin_expect,可以优化分支预测,提高性能。

3. 高级性能优化技术
3.1 缓存优化

现代计算机体系结构中,缓存是提高数据访问速度的关键组件。理解缓存的工作原理对于优化程序性能至关重要。缓存优化主要包括两个方面:缓存行利用和减少缓存失效。

3.1.1 缓存行利用

缓存是由缓存行组成的,通常是 64 字节。当数据被加载到缓存中时,它会填充整个缓存行。因此,连续的数据访问(如数组访问)可以充分利用缓存行,提高数据访问的局部性。

#include <stdio.h>void cache_line_utilization(int *arr, int n) {for (int i = 0; i < n; i++) {arr[i] = i;}
}int main() {int n = 1024;int arr[n];cache_line_utilization(arr, n);// ...后续使用 arr 的代码...return 0;
}

在上面的代码中,cache_line_utilization 函数通过连续访问数组 arr 来充分利用缓存行,从而提高性能。

3.1.2 减少缓存失效

缓存失效是指缓存中的数据不再有效,需要从主存中重新加载。减少缓存失效可以提高程序性能。

#include <stdio.h>void reduce_cache_misses(int *arr, int n) {for (int i = 0; i < n; i += 64) { // 64 是假设的缓存行大小for (int j = 0; j < 64 && i + j < n; j++) {arr[i + j] = i + j;}}
}int main() {int n = 1024;int arr[n];reduce_cache_misses(arr, n);// ...后续使用 arr 的代码...return 0;
}

在上面的代码中,reduce_cache_misses 函数通过减少跨缓存行的跳跃来减少缓存失效,从而提高性能。

3.2 指令级优化

指令级优化涉及到编译器和处理器的指令集架构。通过理解和利用这些底层细节,可以编写出更高效的代码。

3.2.1 循环展开和向量化

现代处理器通常支持 SIMD(单指令多数据)指令,允许同时对多个数据执行相同的操作。通过循环展开和向量化,可以利用这些指令来提高性能。

#include <stdio.h>
#include <emmintrin.h> // SSE 指令集void vectorization(int *arr, int n, int value) {for (int i = 0; i < n; i += 4) {__m128i vec = _mm_set1_epi32(value); // 创建一个包含 value 的向量_mm_storeu_si128((__m128i *)&arr[i], vec); // 将向量存储到 arr 中}
}int main() {int n = 1024;int arr[n];vectorization(arr, n, 5);// ...后续使用 arr 的代码...return 0;
}

在上面的代码中,我们使用了 SSE 指令集来实现向量化。这种方法可以显著提高性能,尤其是在处理大型数据集时。

3.2.2 分支预测优化

现代处理器使用分支预测来猜测程序的控制流,以提高指令流水线的效率。优化分支可以提高性能。

#include <stdio.h>int main() {int arr[1024];for (int i = 0; i < 1024; i++) {arr[i] = i % 2 == 0 ? i : -i;}// ...后续使用 arr 的代码...return 0;
}

在这个例子中,我们通过条件表达式来优化分支,减少不必要的分支预测错误。

4. 内存管理优化
4.1 静态分配与动态分配

静态分配和动态分配各有优缺点。静态分配在编译时确定内存大小,适用于大小固定的数组。动态分配在运行时确定内存大小,适用于大小不确定的数组。

#include <stdio.h>
#include <stdlib.h>int main() {// 静态分配数组int arr[100];// 动态分配数组int *dynArr = malloc(100 * sizeof(int));if (dynArr == NULL) {fprintf(stderr, "Memory allocation failed\n");exit(EXIT_FAILURE);}// 使用 dynArr 进行操作for (int i = 0; i < 100; i++) {dynArr[i] = i;}// 释放内存free(dynArr);return 0;
}

在上面的代码中,我们展示了静态分配和动态分配的区别,并演示了如何动态分配和释放内存。

4.2 内存对齐

适当对齐数据结构可以提高内存访问速度。减少缓存未命中,提高性能。

#include <stdio.h>
#include <stdalign.h>struct Example {int a;char b;double c;
} __attribute__((aligned(8)));int main() {struct Example ex;printf("Size of struct: %zu\n", sizeof(ex)); // 输出结构体大小return 0;
}

在上面的代码中,通过指定 __attribute__((aligned(8))),我们确保结构体的每个实例在内存中从 8 的倍数地址开始,这有助于提高内存访问的效率,尤其是在 64 位处理器上。

4.3 避免内存泄漏

合理管理动态分配的内存,避免内存泄漏。对于长期运行的程序尤为重要。

#include <stdio.h>
#include <stdlib.h>int main() {int *ptr = malloc(100 * sizeof(int));if (ptr == NULL) {fprintf(stderr, "Memory allocation failed\n");exit(EXIT_FAILURE);}// 使用 ptr 进行操作for (int i = 0; i < 100; i++) {ptr[i] = i;}// 释放内存free(ptr);return 0;
}

在上面的代码中,我们展示了如何动态分配内存并在使用完毕后释放内存,避免内存泄漏。

5. 算法和数据结构优化
5.1 选择合适的算法和数据结构

选择合适的算法和数据结构可以显著提高程序的效率。例如,对于需要频繁插入和删除操作的数据,使用链表比使用数组更高效。

#include <stdio.h>
#include <stdlib.h>typedef struct Node {int data;struct Node *next;
} Node;void insert(Node **head, int value) {Node *new_node = (Node *)malloc(sizeof(Node));new_node->data = value;new_node->next = *head;*head = new_node;
}int main() {Node *head = NULL;insert(&head, 1);insert(&head, 2);// ...后续操作...return 0;
}

在上面的代码中,我们使用链表来实现插入和删除操作,相比于数组,链表的插入和删除操作更高效。

5.2 查表优化

查表是一种常见的优化技术,特别是在需要频繁进行相同计算的情况下。通过预先计算并将结果存储在表中,可以避免在运行时重复计算。

#include <stdio.h>static long factorial_table[] = {1, 1, 2, 6, 24, 120, 720 /* etc */ };long factorial(int i) {return factorial_table[i];
}int main() {int i = 5;printf("Factorial of %d is %ld\n", i, factorial(i));return 0;
}

在上面的代码中,我们预先计算了阶乘值并存储在 factorial_table 数组中,通过查表来获取阶乘值,避免了在运行时重复计算。

5.3 使用位操作

位操作可以直接操作数据的最小单元——位,常用于优化数据结构和实现加密算法。

#include <stdio.h>int main() {unsigned char flags = 0;flags |= (1 << 2);  // 设置第3位flags &= ~(1 << 2); // 清除第3位printf("Flags: %02X\n", flags);return 0;
}

在上面的代码中,我们使用位操作来设置和清除特定的位,这种方式比使用布尔变量更高效。

6. 并行计算和多线程优化
6.1 使用多线程

多线程可以充分利用多核处理器的计算能力,提高程序的执行效率。C 语言中可以使用 POSIX 线程库(pthread)来实现多线程。

#include <stdio.h>
#include <pthread.h>void *thread_function(void *arg) {int *data = (int *)arg;for (int i = 0; i < 1000000; i++) {(*data)++;}return NULL;
}int main() {pthread_t threads[4];int data[4] = {0};for (int i = 0; i < 4; i++) {pthread_create(&threads[i], NULL, thread_function, &data[i]);}for (int i = 0; i < 4; i++) {pthread_join(threads[i], NULL);}for (int i = 0; i < 4; i++) {printf("Thread %d result: %d\n", i, data[i]);}return 0;
}

在上面的代码中,我们创建了 4 个线程,每个线程独立地对一个整数进行累加操作。通过多线程,可以显著提高计算效率。

6.2 使用 OpenMP

OpenMP 是一种并行编程模型,可以简化多线程编程。通过在代码中添加简单的指令,可以轻松实现并行计算。

#include <omp.h>
#include <stdio.h>int main() {int sum = 0;#pragma omp parallel for reduction(+:sum)for (int i = 0; i < 1000000; i++) {sum += i;}printf("Sum: %d\n", sum);return 0;
}

在上面的代码中,我们使用 OpenMP 的 #pragma omp parallel for 指令将循环并行化,并使用 reduction 子句来处理累加操作。通过这种方式,可以显著提高计算效率。

7. 性能分析和调试
7.1 使用性能分析工具

为了有效地进行性能优化,需要使用一系列的性能分析工具来识别和诊断性能瓶颈。以下是一些常用的性能分析工具及其使用场景。

  • gprof:一个功能强大的性能分析工具,可以显示程序运行的 CPU 时间分布,帮助开发者找到优化的热点。
  • Valgrind:一个编程工具,主要用于内存调试、内存泄漏检测和性能分析。其性能分析工具 Callgrind 可以生成详细的调用图和性能数据。
  • perf:Linux 内核提供的一个性能分析工具,可以用来分析程序的性能问题,特别是 CPU 缓存使用、分支预测等方面。
# 使用 gprof
gcc -pg -o my_program my_program.c
./my_program
gprof my_program > profile.txt# 使用 Valgrind
valgrind --tool=callgrind ./my_program# 使用 perf
perf record -g ./my_program
perf report
7.2 性能优化原则

在进行性能优化时,应遵循以下原则:

  • 先测量,后优化:不要基于猜测进行优化,而是要通过测量来确定性能瓶颈。
  • 关注主要矛盾:优化那些对性能影响最大的部分,遵循 80/20 法则。
  • 逐步迭代:性能优化是一个迭代过程,需要逐步调整和验证。
  • 保持代码可读性:在优化性能的同时,尽量保持代码的清晰和可维护性。
8. 实际应用案例
8.1 用户输入验证

在实际开发中,用户输入验证是一个常见的应用场景。通过 scanf 函数可以方便地读取用户的输入并进行验证。

#include <stdio.h>
#include <stdlib.h>int main() {int age;printf("请输入您的年龄:");if (scanf("%d", &age) != 1 || age <= 0) {printf("无效的年龄输入!\n");return 1;}printf("您的年龄:%d\n", age);return 0;
}
8.2 文件读取

scanf 函数可以结合文件输入流读取文件中的数据。

#include <stdio.h>int main() {FILE *file = fopen("data.txt", "r");if (file == NULL) {perror("文件打开失败");return 1;}int a, b;if (fscanf(file, "%d %d", &a, &b) != 2) {printf("文件读取错误!\n");fclose(file);return 1;}printf("文件中的数据:a = %d, b = %d\n", a, b);fclose(file);return 0;
}
8.3 数据解析

scanf 函数可以用于解析复杂的输入数据格式。

#include <stdio.h>int main() {char name[50];int age;float salary;printf("请输入员工信息(姓名 年龄 薪水):");if (scanf("%49s%d%f", name, &age, &salary) != 3) {printf("输入格式错误!\n");return 1;}printf("员工信息:姓名:%s,年龄:%d,薪水:%.2f\n", name, age, salary);return 0;
}
9. 总结

C 语言因其高效、灵活和功能强大而广受欢迎。通过理解底层优化、编译器优化、内存管理和高级编程技巧,程序员可以编写出性能卓越的 C 程序。本文提供了详细的优化策略和代码案例,希望对读者深入理解 C 语言性能优化有所帮助。在实际应用中,性能优化是一个复杂的过程,需要根据具体的应用场景和目标平台进行细致的分析和调整。

参考文献

[1] C语言代码优化11种实用方法 - 知乎
[2] C语言程序性能优化:十大策略及代码案例解析
[3] C语言代码优化艺术:深入细节,提升效率与性能的实践指南
[4] 高性能计算|C语言常见优化策略 - 知乎
[5] C语言性能优化 - 裸睡的猪 - 博客园
[6] 超全 | 只有高手才知道的C语言高效编程与代码优化方法(一 …
[7] C语言性能优化 - CSDN博客
[8] C语言代码优化方法详解 - CSDN博客
[9] 优化C/C++代码性能的27条建议——<Tips for Optimizing C …
[10] 18|极致优化(上):如何实现高性能的 C 程序?
[11] C语言代码性能优化:提升程序效率的10大技巧 - CSDN文库
[12] C语言性能深度剖析:从底层优化到高级技巧及实战案例分析
[13] C语言性能优化参考手册 - CSDN博客
[14] C语言程序性能优化:十大策略及代码案例解析
[15] 性能优化技巧:C语言程序的高效实现 - CSDN文库
[16] C语言代码优化实战指南与案例分析 - CSDN文库
[17] [大师C语言 (第十篇)]C语言性能优化的技术详解_c语言性能 …
[18] 如何在C语言中优化代码性能 - PingCode
[19] 高性能计算|C语言常见优化策略 - 知乎
[20] 19|极致优化(下):如何实现高性能的 C 程序?-深入C语言 …
[21] 【C 言专栏】优化 C 语言程序性能的策略 - 阿里云开发者社区
[22] c语言如何提高性能 | PingCode智库

相关文章:

C语言性能优化:从基础到高级的全面指南

引言 C 语言以其高效、灵活和功能强大而著称&#xff0c;被广泛应用于系统编程、嵌入式开发、游戏开发等领域。然而&#xff0c;要写出高性能的 C 语言代码&#xff0c;需要对 C 语言的特性和底层硬件有深入的了解。本文将详细介绍 C 语言性能优化的背后技术&#xff0c;并通过…...

常用的公共 NTP(网络时间协议)服务器

公共 NTP 服务列表 以下是一些常用的公共 NTP&#xff08;网络时间协议&#xff09;服务器&#xff0c;供您参考&#xff1a; 中国地区公共 NTP 服务器 国家授时中心 NTP 服务器&#xff1a;ntp.ntsc.ac.cn中国 NTP 快速授时服务&#xff1a;cn.ntp.org.cn阿里云公共 NTP 服务…...

Kafka中的Topic和Partition有什么关系?

大家好&#xff0c;我是锋哥。今天分享关于【Kafka中的Topic和Partition有什么关系&#xff1f;】面试题。希望对大家有帮助&#xff1b; Kafka中的Topic和Partition有什么关系&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在 Apache Kafka 中&#…...

Unity 使用UGUI制作卷轴开启关闭效果

视频效果 代码 using UnityEngine.UI; using System.Collections; using System.Collections.Generic; using UnityEngine; using DG.Tweening; using DG.Tweening.Core; using DG.Tweening.Plugins.Options;public class JuanZhou : MonoBehaviour {[SerializeField]private …...

MarkDown怎么转pdf;Mark Text怎么使用;

MarkDown怎么转pdf 目录 MarkDown怎么转pdf先用CSDN进行编辑,能双向看版式;标题最后直接导出pdfMark Text怎么使用一、界面介绍二、基本操作三、视图模式四、其他功能先用CSDN进行编辑,能双向看版式; 标题最后直接导出pdf Mark Text怎么使用 Mark Text是一款简洁的开源Mar…...

整合版canal ha搭建--基于1.1.4版本

开启MySql Binlog&#xff08;1&#xff09;修改MySql配置文件&#xff08;2&#xff09;重启MySql服务,查看配置是否生效&#xff08;3&#xff09;配置起效果后&#xff0c;创建canal用户&#xff0c;并赋予权限安装canal-admin&#xff08;1&#xff09;解压 canal.admin-1…...

QGIS移动图元功能

有时需要在QGIS里面移动一些矢量图层&#xff0c;比如图层的地理配准&#xff0c;网上搜了一些资料没有查看&#xff0c;后来仔细找了下&#xff0c;在编辑-编辑几何图形-移动要素里面&#xff0c;可以移动图层。 注意&#xff1a;移动前先要选择上要移动的图层&#xff0c;之…...

【模电刷题复习--填空】

如有错误&#xff0c;欢迎各位大佬在评论区批评指正 模电刷题 一、填空题1.本征半导体中&#xff0c;若掺入微量的__五__价元素&#xff0c;则形成___n___型半导体&#xff0c;其多数载流子是自由电子&#xff0c;若掺入微量的__三__价元素&#xff0c;则形成__p__型半导体。其…...

shardingsphere-jdbc-core-spring-boot-starter的性能问题(理论)

hardingSphere-JDBC-core-spring-boot-starter 是 ShardingSphere 提供的与 Spring Boot 集成的模块&#xff0c;用于实现数据库的分库分表等功能。在性能方面&#xff0c;它既有优势也存在一定的挑战&#xff0c;以下是具体分析&#xff1a; 优势方面 数据分片提升查询性能 通…...

Java Map 集合详解:基础用法、常见实现类与高频面试题解析

在 Java 集合框架中&#xff0c;Map 是用于存储键值对&#xff08;Key-Value&#xff09;的重要接口&#xff0c;广泛应用于开发中的各种场景。本文将详细讲解 Map 的基础概念、常见实现类及其特性&#xff0c;并结合代码示例和高频面试问题&#xff0c;帮助你深入理解 Map 的用…...

一款基于.Net方便、快捷的数据库文档查询、生成工具

项目介绍 SmartSQL 是一款方便、快捷的数据库文档查询、导出工具&#xff01;从最初仅支持SqlServer数据库、CHM文档格式开始&#xff0c;通过不断地探索开发、集思广益和不断改进&#xff0c;又陆续支持Word、Excel、PDF、Html、Xml、Json、MarkDown等文档格式的导出。同时又…...

Linux平台下实现的小程序-进度条

目录 1.换行、回车概念 2.缓冲区 2.1缓冲区 2.2强制刷新 3.进度条程序 Makefile文件 ProgressBar.h ProgressBar.c Main.c 执行结果 1.换行、回车概念 /n&#xff1a;换行回车&#xff08;\r&#xff1a;回车&#xff09; 2.缓冲区 如下图在vim编辑器中的命令模式下…...

Ubuntu 22.04.5 修改IP

Ubuntu22.04.5使用的是netplan管理网络&#xff0c;因此需要在文件夹/etc/netplan下的01-network-manager-all.yaml中修改&#xff0c;需要权限&#xff0c;使用sudo vim或者其他编辑器&#xff0c;修改后的内容如下&#xff1a; # Let NetworkManager manage all devices on …...

解决virtualbox出现开启DHCP之后ubuntu虚拟机之后IP重复的问题

找遍了国内论坛&#xff0c;没一个能解决该问题的&#xff0c;所以我自己写个文章吧&#xff0c;真讨厌那些只会搬运的&#xff0c;污染国内论坛环境&#xff0c;搜一个问题&#xff0c;千篇一律。 问题 操作系统版本为"Ubuntu 24.04 LTS" lennytest1:~$ cat /etc…...

Java开发工具-Jar命令

Java开发工具-Jar 1、jar命令全平台使用 2、jar命令的作用 为类和资源创建存档&#xff0c;并从存档中操作或恢复单个类或资源 3、摘要 jar [OPTION …] [ [–release VERSION] [-C dir] files] … 4、jar命令描述 jar命令通常作为用于压缩与解压的工具&#xff0c;基于ZIP或Z…...

UE5通过蓝图节点控制材质参数

通过蓝图节点控制材质的参数 蓝图节点 在材质上设置标量值 和 在材质上设置向量参数值 Set Scalar Parameter Value on Materials Set Vector Parameter Value on Materials 这两个蓝图节点都可以在蓝图中&#xff0c;控制材质的参数值和向量值...

敖行客年终总结-AT Work 1.0发布

2024年就要过去了&#xff0c;看看敖行客这一年都干了些啥&#xff1f; 敖行客团队通过整整一年的努力&#xff0c;正式推出了AT Work 1.0订阅版&#xff0c;这也标志着AT Work即将正式和C端的小伙伴见面了。 AT Work 是什么&#xff1f; 长期以来&#xff0c;软件研发成本、…...

线程锁和协程锁的区别

转自&#xff1a;chatgpt 1.bthread_mutex_t bthread_mutex_t 是 brpc 框架提供的一种互斥锁&#xff0c;专门为 bthread&#xff08;轻量级线程&#xff09; 设计&#xff0c;具有以下特点&#xff1a; 适用于 bthread 调度模型&#xff1a; bthread_mutex_t 是为 brpc 中的…...

手机租赁平台开发助力智能设备租赁新模式

内容概要 手机租赁平台开发&#xff0c;简单说就是让你用得起高大上的智能设备&#xff0c;不管是最新款的手机、平板&#xff0c;还是那些炫酷的智能耳机&#xff0c;这个平台应有尽有。想要体验但又不希望花大钱&#xff1f;那你就找对地方了&#xff01;通过灵活的租赁方案…...

掌握大数据处理利器:Flink 知识点全面总结【上】

1.Flink的特点 Apache Flink 是一个框架和分布式处理引擎&#xff0c;用于对无界和有界数据流进行状态计算。 Flink主要特点如下&#xff1a; 高吞吐和低延迟。每秒处理数百万个事件&#xff0c;毫秒级延迟。结果的准确性。Flink提供了事件时间(event--time)和处理时间(proces…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

SkyWalking 10.2.0 SWCK 配置过程

SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外&#xff0c;K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案&#xff0c;全安装在K8S群集中。 具体可参…...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言&#xff1a; 通过AI视觉技术&#xff0c;为船厂提供全面的安全监控解决方案&#xff0c;涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面&#xff0c;能够实现对应负责人反馈机制&#xff0c;并最终实现数据的统计报表。提升船厂…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?

uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件&#xff0c;用于在原生应用中加载 HTML 页面&#xff1a; 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?

现有的 Redis 分布式锁库&#xff08;如 Redisson&#xff09;相比于开发者自己基于 Redis 命令&#xff08;如 SETNX, EXPIRE, DEL&#xff09;手动实现分布式锁&#xff0c;提供了巨大的便利性和健壮性。主要体现在以下几个方面&#xff1a; 原子性保证 (Atomicity)&#xff…...

c++第七天 继承与派生2

这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分&#xff1a;派生类构造函数与析构函数 当创建一个派生类对象时&#xff0c;基类成员是如何初始化的&#xff1f; 1.当派生类对象创建的时候&#xff0c;基类成员的初始化顺序 …...

python爬虫——气象数据爬取

一、导入库与全局配置 python 运行 import json import datetime import time import requests from sqlalchemy import create_engine import csv import pandas as pd作用&#xff1a; 引入数据解析、网络请求、时间处理、数据库操作等所需库。requests&#xff1a;发送 …...