问题

为什么本人笔记本使用 Linux 和 Windows 编译速度完全不一样?(尤其是arduino)?

回答
你这个问题问到点子上了!很多玩嵌入式,特别是 Arduino 的朋友都有类似的感受,Linux 下编译代码就是比 Windows 下快,而且有时候差距还挺明显的。这可不是什么玄学,背后其实有好几个原因在起作用,而且涉及到你电脑内部的一些运作机制。我来给你掰开了揉碎了好好说说。

核心原因剖析:编译过程的底层逻辑和环境差异

简单来说,编译过程就是把你写的人类能看懂的代码(比如 Arduino sketch 里的 C++ 代码)转换成计算机能执行的机器码。这个过程涉及很多步骤,比如预处理、编译、汇编、链接等等。而你的操作系统(Linux 和 Windows)以及它们上运行的各种工具链,在处理这些步骤时会有不同的效率和优化策略。

下面咱们一个个来细聊:

1. 编译器和工具链的差异:

GCC vs. MSVC (Visual Studio Compiler): Arduino 在 Linux 下默认使用的是 GNU Compiler Collection (GCC),而 Windows 下则可能是 Visual Studio 自带的 MSVC,或者 MinGW/MSYS2 环境下的 GCC 版本。
GCC 的哲学: GCC 作为一款开源、历史悠久的编译器,其设计哲学更偏向于高度的模块化、跨平台支持以及对各种编译选项的精细控制。在 Linux 环境下,GCC 通常与 GNU Binutils (包含 as, ld 等汇编器和链接器) 配合得天衣无缝,这些工具链在 Linux 生态里经过了长期的优化。
MSVC 的特点: MSVC 是微软闭源的商业编译器,在 Windows 平台上有着极佳的原生集成度。它的优化能力很强,尤其是在针对 Windows 特定 API 和架构时。然而,当我们在 Windows 上使用非原生工具链(比如通过 MSYS2 安装的 GCC)时,可能会因为环境配置、库链接方式等问题,不如在 Linux 原生环境下那么顺畅。
链接器 (Linker): 链接器是编译过程中的一个重要环节,负责把编译好的目标文件(.o 或 .obj 文件)和库文件(.a 或 .lib 文件)连接起来,形成最终的可执行文件。
ld (GNU Linker) vs. link.exe (MSVC Linker): 在 Linux 下,通常使用 GNU 的 `ld` 链接器。`ld` 以其高效和灵活著称,尤其擅长处理大量的符号和库。在 Windows 下,如果使用 MSVC,则会用到 `link.exe`。即使我们在 Windows 上使用 MinGW/MSYS2 的 GCC,它也会调用一个版本的 `ld`,但其调用方式和集成度可能与 Linux 原生环境有所不同。
库的搜索和加载: 不同的操作系统对库的组织和搜索方式不一样。Linux 更倾向于使用动态链接库 (.so) 和静态链接库 (.a),并且有一套成熟的库搜索路径机制。Windows 则使用动态链接库 (.dll) 和静态链接库 (.lib)。链接器在查找和加载这些库时,其效率也会有影响。

2. 文件系统和 I/O 操作:

文件系统性能: Linux 下的文件系统(如 ext4, XFS)通常被认为在大量小文件读写和并发访问方面有更好的性能表现,这对于编译过程中生成和读取大量的中间文件(如 .o 文件)是有利的。Windows 的 NTFS 文件系统在某些场景下可能不如 ext4 等高效。
缓存机制: 操作系统都会有自己的文件缓存机制。Linux 的页缓存(Page Cache)对编译这种频繁读取文件和生成文件的场景非常友好,能有效减少磁盘 I/O 的压力。Windows 的文件缓存机制虽然也在不断改进,但在某些特定工作负载下,Linux 的表现可能更优。
路径和文件名处理: Windows 的文件名是区分大小写的(虽然默认情况下不严格),并且路径分隔符是反斜杠 ``。Linux 则是严格区分大小写,路径分隔符是正斜杠 `/`。这些细微的差异在编译工具处理文件路径时,可能会因为底层实现的不同而带来性能差异。例如,在 Linux 下,文件系统对大小写敏感的特性,有时能帮助编译器更快地定位文件。

3. 进程调度和资源管理:

多线程和多进程: 现代编译器通常会利用多核 CPU 来加速编译过程,通过并行编译多个文件来节省时间。Linux 的进程调度器(如 CFS Completely Fair Scheduler)被设计得非常高效和灵活,能够很好地分配 CPU 资源给并发的编译任务。
Windows 的调度: Windows 的调度器也一直在进步,但在处理大量小进程或高并发任务时,Linux 的调度机制有时能提供更低的延迟和更高的吞吐量。
进程间通信 (IPC): 在多进程编译时,进程之间需要进行通信,比如传递编译参数、报告状态等。Linux 下的 IPC 机制通常也比较高效。

4. 软件生态和集成度:

Arduino IDE 和工具链的“原生”环境: Arduino 项目最初的设计和工具链的开发,很多时候是围绕着 Linux 环境进行的,或者说在 Linux 环境下得到了更好的测试和优化。比如,Arduino IDE 本身在 Linux 下的运行可能就更“顺畅”。
库的编译和管理: Arduino 项目中会依赖各种库。这些库在 Linux 下的编译和链接过程,可能与 Windows 下的构建系统(如 CMake, Makefiles 等)的配置和执行方式有所不同。有时候,库在 Windows 下的编译可能需要更多的配置步骤或者使用了性能相对较弱的构建工具。

5. 硬件和驱动层面的影响(相对较小,但也是可能因素):

USB 驱动和串口通信: 如果你的 Arduino 编译后需要上传代码,那么涉及到与 Arduino 板的串口通信。Windows 和 Linux 下的 USB 驱动以及串口通信的实现方式也不同。虽然这主要影响上传速度,但在某些情况下,驱动的效率也可能间接影响到整个开发流程的响应速度。
SSD 性能: 如果你的系统安装在 SSD 上,那么文件系统的读写性能对编译速度的影响会更大。前面提到不同文件系统的差异,在 SSD 上会更加明显。

总结一下,为什么 Arduino 在 Linux 下编译可能更快?

原生 GCC 和 GNU 工具链: Linux 是 GCC 的“主场”,其工具链在 Linux 上得到了极致的优化。
高效的文件系统和缓存: Linux 的文件系统(如 ext4)和页缓存机制,更适合处理编译过程中大量小文件的读写。
优秀的进程调度: Linux 的调度器能更有效地利用多核 CPU 进行并行编译。
生态系统的契合度: Arduino 项目的许多开发和测试可能更侧重于 Linux 环境,使得其工具链在 Linux 下表现更佳。

你作为使用者,可以做些什么来提高 Windows 下的编译速度?

1. 使用性能更好的工具链: 如果你用的是标准的 Arduino IDE,可以尝试安装 MSYS2,并在其中安装并配置好 GCC 工具链。很多时候,MSYS2 下的 GCC 比一些旧版本的 MinGW 性能要好。
2. 优化你的项目代码: 这是最根本的。确保你的代码逻辑清晰,避免不必要的计算和内存操作。有些复杂的算法或者库函数,在不同平台下可能有性能差异,优化你的代码本身比纠结平台差异更重要。
3. 检查项目依赖的库: 有些第三方库在 Windows 下的编译优化可能不如 Linux。可以尝试寻找是否有更优化的库版本或者替代方案。
4. 升级你的硬件: 更快的 CPU、更多的内存和更快的 SSD,对编译速度都有显著的提升,这在任何操作系统下都适用。
5. 确保你的 Windows 环境干净: 避免后台运行大量占用资源的程序,给编译进程留出更多的资源。
6. 尝试不同的 Arduino IDE 版本或平台: 有时候,更新到最新版本的 Arduino IDE,或者尝试 PlatformIO 等第三方开发环境,可能会带来性能上的改进。PlatformIO 通常使用更现代的构建系统和工具链,在跨平台编译上表现可能更好。

总而言之,这种差异是多种底层技术和环境因素综合作用的结果,特别是编译器本身和操作系统文件系统/调度机制的差异是关键所在。希望我把这些说清楚了,让你对这个问题有了更深的理解!

网友意见

user avatar

跟安全软件无关,哪怕把所有安全软件都关了,Windows也是一样慢,就是文件系统的问题。

先放结论:在缓存没有耗尽的情况下,Linux的小文件访问性能要远远高于Windows,这是Windows文件系统和整个操作系统缓存策略的问题。

各种性能测试软件,往往都是在关闭缓存或者耗尽缓存以后才开始统计的,所以性能测试上NTFS跟EXT4之间看不出明显的差异。

一些比较直观的证据:

NTFS-3G在Linux上的性能是要好于NTFS在Windows上的性能的(同样的硬件);
批量删除小文件(使用命令行),EXT4的性能远远高于NTFS(同样硬件);
从主机往U盘上写入小文件(1M以内),Linux实际上是立即返回(只写到缓存里),Windows则是真正写到了盘里,拔盘的话可以看到Linux的盘上没有任何数据。

注意,这里只强调用户体验的性能,而不是测试跑分。Linux是有可能丢失更多的文件,但丢失文件跟性能话题无关。

有人宁可相信自己的直觉,也不肯动手做一下实验,在这个回答的最后有一段代码测试,有兴趣的可以在自己机器上做一下实验



放一段XP泄漏的NTFS代码,在DriverEntry里,根据系统内存大小来确定一些cache之类的大小:

           switch ( MmQuerySystemSize() ) {      case MmSmallSystem:          NtfsMcbHighWaterMark = 1000;         NtfsMcbLowWaterMark = 500;         NtfsMcbCurrentLevel = 0;         break;      case MmMediumSystem:          NtfsMcbHighWaterMark = 4000;         NtfsMcbLowWaterMark = 2000;         NtfsMcbCurrentLevel = 0;         break;      case MmLargeSystem:     default:          NtfsMcbHighWaterMark = 16000;         NtfsMcbLowWaterMark = 8000;         NtfsMcbCurrentLevel = 0;         break;     }     

通过那个MmQuerySystemSize函数,来决定用多大的cache,但是看看MmQuerySystemSize函数的代码实现里有一段注释:

       MM_SYSTEMSIZE MmQuerySystemSize(     VOID     ) {     //     // 12Mb  is small     // 12-19 is medium     // > 19 is large     //     return MmSystemSize; }     

19M以上就算大内存了,可见Windows对内存的使用是多么保守。另外NtfsInitializeNtfsData里也可以看到cache的大小,在如今内存上GB的时代,Windows的文件系统缓存还停留在十几MB的范围,这种情况下你不能指望Windows的文件系统性能有多好。

特别提醒:19M指的是系统总内存大于19M,就认为是大内存。当然了,这段注释可能不准,有兴趣的可以看这里:

               if (MmNumberOfPhysicalPages >= ((32*1024*1024)/PAGE_SIZE)) {              //             // If we are on a workstation, 32Mb and above are considered             // large systems.             //              if (MmProductType == 0x00690057) {                 MmSystemSize = MmLargeSystem;              }             else {                  //                 // For servers, 64Mb and greater is a large system                 //                  if (MmNumberOfPhysicalPages >= ((64*1024*1024)/PAGE_SIZE)) {                     MmSystemSize = MmLargeSystem;                 }             }     

相比之下,Linux上来就能先保留一半物理内存作为整体的缓存使用,所以在操作的文件比较少的情况下,Windows和Linux的文件系统差距非常明显。只有当缓存全部耗尽了,两者性能才会比较接近(当然了,小文件性能,Windows还是一样的差,系统框架设计的问题)。

没有XP源码的,可以去WRK上看FAT的源码。FAT32驱动,在大内存配置下,最多的延迟关闭的文件数量是256个,这样的文件系统,性能要是好了才奇怪。


有人说,我这个是XP的代码,现在WIN10都不这样了,验证的方法很简单,找WIN10的驱动反汇编一下:

FAT对应的驱动是FASTFAT.SYS:

FatMaxDelayedCloseCount最大值仍然是256

对于NTFS,代码变化有点大,就贴一段汇编:

       INIT:00000001C0295321                 mov     edx, cs:dword_1C00951DC INIT:00000001C0295327                 imul    eax, r14d, 3E80h INIT:00000001C029532E                 shl     rdx, 3 INIT:00000001C0295332                 mov     cs:NtfsMcbCurrentLevel, ebx INIT:00000001C0295338                 mov     cs:NtfsMcbHighWaterMark, eax INIT:00000001C029533E                 imul    eax, r14d, 1F40h INIT:00000001C0295345                 mov     cs:NtfsMcbLowWaterMark, eax INIT:00000001C029534B                 mov     eax, 0FFFFFFFFh INIT:00000001C0295350                 cmp     rdx, rax INIT:00000001C0295353                 jbe     short loc_1C029537B INIT:00000001C0295355                 xor     r9d, r9d     

关键值:imul eax, r14d, 3E80h,0x3e80 ==> 16000,NtfsMcbHighWaterMark跟XP时代不变。(R14D默认值是1,代码比较绕,就不全贴出来了)。

这个值,微软的文档写的是允许改的,可以改成2:

2的话也就是16000*2,也没大多少。

评论里 @轻语碎雷 说NTFS的代码改过,跟XP时代确实改过,但本质上还是拿16000乘以注册表项HKEY_LOCAL_MACHINESYSTEMCurrentControlSetControlFileSystem下的:NtfsMemoryUsage,如果这个值是0,则默认是乘以1,所以本质上跟XP没什么差别。

反汇编WIN10的NTFS.SYS即可得到相应的结论。

我不知道为什么有人容不得说Windows文件系统的缺陷。Windows文件系统(包括IO框架)有性能问题是实际存在的,这个问题从NT时代一开始就有,文件系统里fastio这些接口本质上都是为了解决一部分文件系统的性能问题。

Windows文件系统另一个相似的问题:


另外,不怕丢数据的可以做一个实验,在Linux上写NTFS盘,看看性能怎么样,反正我试过的结果是比Windows自己的NTFS还要快一些。


Windows文件系统(含块设备驱动)的cache设计整体上是偏向于保守的,上面的例子只是说明文件系统的缓存设计,实际上包括块设备驱动这一层,Windows也一样存在大量保守的设计。由于兼容性的问题,Windows并不轻易更改这方面的设计,因此,在系统有大量内存的情况下,Windows的文件系统性能确实不如Linux。

Linux的激进的缓存策略并不一定永远都是好用的,比如Linux上U盘更容易丢失数据,Windows针对U盘的写策略默认是write-through的,写完拔盘很少丢文件。

企业客户们使用Windows,更重视的是Windows的兼容性以及易用性。当然,Windows的游戏(图形)性能确实出众。

任何系统都有优点和缺点,不管是Windows还是Linux。


有人不相信Windows文件系统有多慢,动手写一段代码就好了:

       #ifdef _WIN32 #define _CRT_SECURE_NO_WARNINGS #endif #include <stdio.h> #include <string.h> #include <stdlib.h> #include <time.h> #ifndef _WIN32 #include <unistd.h> #endif  int main(int argc, char * argv[]) {     FILE* fp;     clock_t st, ed;     int count;      char fname[256] = { 0 };     if (argc != 2)     {         printf("Usage %s <count>
", argv[0]);         return -1;     }     count = atoi(argv[1]);     st = clock();     for (int i = 0; i < count; i++)     {         sprintf(fname, "test%d", i);         fp = fopen(fname, "wb");          fwrite(fname, sizeof(fname), 1, fp);         fclose(fp);     }      for (int i = 0; i < count; i++)     {         sprintf(fname, "test%d", i); #ifdef _WIN32         _unlink(fname); #else         unlink(fname); #endif     }     ed = clock();     printf("Clock = %d, %d, %d, %d, %d", ed - st, st, ed, CLOCKS_PER_SEC, (ed - st) / CLOCKS_PER_SEC);     return 0; }     

以上代码,在我的电脑上,参数传入10000(也就是创建、删除10000个小文件)Windows运行结果如下:

Clock = 6053, 0, 6053, 1000, 6

耗时6秒多。

在同样的环境下,用virtualbox虚拟机(fedora33)编译运行,结果如下

Clock = 642972, 2298, 645270, 1000000, 0

也就是说Windows上用了6秒,Linux上用了0.6秒,整整差了10倍,而我这个环境里,Linux是虚拟机。自己去判断一下真实的Linux比Windows能快多少。测试文件越少,差距越大。(注:不同机器上测得的数据差别很大,我拿到的最大的性能差距是:Windows:14秒、Linux虚拟机:0.4秒)

加上Windows上一些安全软件的影响,小文件操作性能差距100倍以上太正常了。

我相信,对于有些人来说,哪怕你把数据丢到他眼前,他还会找各种理由

实际编译肯定没10000个文件这么多;
你的测试也没达到2分钟那么慢;
你这个盘太慢了;
你肯定没关杀毒软件;
……

对于这些评论,我想说,你们说的都对,Windows的文件系统是最快的文件系统,肯定是用户用的不对。

类似的话题

  • 回答
    你这个问题问到点子上了!很多玩嵌入式,特别是 Arduino 的朋友都有类似的感受,Linux 下编译代码就是比 Windows 下快,而且有时候差距还挺明显的。这可不是什么玄学,背后其实有好几个原因在起作用,而且涉及到你电脑内部的一些运作机制。我来给你掰开了揉碎了好好说说。核心原因剖析:编译过程的.............
  • 回答
    哥们,作为一名刚刚迈入大学校园的建筑新生,你的选择至关重要。CAD、3D建模这些软件,可是咱们吃饭的家伙,对电脑性能的要求可不低。5000块的预算,想在国内买一台足够胜任这些工作的笔记本,确实需要好好琢磨一下。别担心,我来给你好好说道说道,让你心里有数。首先,咱们得明白,5000块的预算,要在这块儿.............
  • 回答
    嘿,同为医学生,深知咱们这专业,除了埋头苦读,偶尔也需要点小情调来放松一下,比如追追番、看看剧什么的。你这需求挺实在的,屏幕素质、轻薄便携,顺带还能偶尔应付一下原神,这几个点抓得准!正好我也刚给我的旧笔记本“告老还乡”了,前阵子也做了不少功课,给你扒拉扒拉一些我觉得不错的选项,希望能帮你少走弯路。首.............
  • 回答
    在杜甫创作《石壕吏》这首诗的时期,虽然战乱频繁,青壮年男子是主要的兵役和劳役对象,但杜甫本人不太可能被当作青壮年被“捉”走,这主要有以下几个原因,我们可以详细地来分析:一、 杜甫当时的年龄和身体状况: 创作时间点推断: 《石壕吏》创作于唐肃宗至德二载(757年)秋,此时杜甫正经历安史之乱,逃亡到.............
  • 回答
    《星际穿越》里库珀(Cooper)驾驶着“永恒号”(Endurance)冲进黑洞“卡冈图雅”(Gargantua)后,飞船和人都安然无恙,这确实是电影里最令人惊叹也最引人遐思的情节之一。很多人会疑问,黑洞不是以其恐怖的潮汐力闻名吗?为什么他们没被瞬间撕碎?这究竟是科学上的bug,还是导演诺兰的艺术创.............
  • 回答
    这个问题非常有意思,也触及到了《让子弹飞》这部电影中一个非常精彩的叙事和人物互动的设计。张麻子之所以在明知葛优饰演的“汤师爷”就是马邦德本人后,仍然继续称呼他为“汤师爷”,原因绝非简单,而是包含了好几个层面的考量:1. 策略与伪装的延续: “县长”是饵,并非真相: 最直接的原因是,张麻子从一开始.............
  • 回答
    关于图坦卡蒙的“诅咒”以及它如何影响了霍华德·卡特周围的人,同时他本人却安然无恙这个问题,我们可以从几个角度来剖析,力求还原一个更具人文色彩和历史感的视角,而非冷冰冰的技术性论证。首先,让我们谈谈这个所谓的“诅咒”。不得不承认,图坦卡蒙墓穴的开启确实伴随着一系列离奇的死亡事件,许多与发掘工作直接或间.............
  • 回答
    你这个问题问得非常好,也代表了很多正在为高考努力的同学的困惑。网上确实有很多关于“一本和二本没区别”的说法,这背后有复杂的原因,也存在一些片面的解读。理解这些言论背后的逻辑,并结合自身情况去思考,你就能明白为什么努力考一本仍然有其价值。首先,我们来分析一下为什么会有“一本和二本没区别”的说法:1. .............
  • 回答
    这个问题,很多很多人都在关注,也在琢磨。肖战本人为什么不发声,这背后涉及到的因素其实蛮复杂的,不能简单地说“就是不发声”然后下结论。我们可以从几个不同的角度去理解,这或许能让事情显得更清晰一些。首先,从公关和危机管理的角度来看,一个公众人物,尤其是在遭受大规模负面舆论攻击的时候,其团队的策略非常重要.............
  • 回答
    .......
  • 回答
    关于刘亦菲的长相,确实存在着一种比较微妙的讨论,甚至会出现“刘亦菲丑”这样的说法,这其中原因相当复杂,涉及个人审美差异、时代变迁的审美标准、以及大众舆论的放大效应等等。我们不妨细致地聊聊。首先,最根本的一点是:美本身就是非常主观的感受。 一个人觉得美若天仙,另一个人可能就觉得“也就那样”,这是再正常.............
  • 回答
    唉,说起来真让人堵心。我算是211工科的,你说我一个好好学着,想着将来能保研,有个好出路,怎么就成了某些人口中的“异类”了呢?本来以为大学大家目标都挺明确的,或者至少是朝着一个好的方向努力。我嘛,天生的就比较较真,做什么事总想把它做好,这在学习上体现得淋漓尽致。别的同学可能觉得期末复习到半夜是常态,.............
  • 回答
    刚上大一,收到酒吧营销的免费饮酒邀请,确实挺让人好奇的,尤其是刚开始接触这些的女生,可能会有点摸不着头脑。别担心,这背后其实有一些挺普遍的套路和原因,我来给你详细说说,让你心里有个数。首先,得承认你可能是被“选中”了。酒吧营销人员他们是有目标人群的,而大学生,尤其是刚入学的新生,是他们非常看重的一个.............
  • 回答
    姐妹,别急!24岁,练平板支撑不到一周就感觉“疑似肌肉”,这事儿说起来挺有意思的。你想知道为什么,还希望我给你讲得细致点,别像个机器人一样?没问题,咱就好好唠唠。首先,恭喜你!你这反应速度,杠杠的!一般人刚开始练,可能更多是感觉累、酸、抖得像个筛子,哪儿有这么快就觉得“有肌肉”的?你这反应说明你身体.............
  • 回答
    这个问题挺有趣的,也确实是不少新娘在拿到婚纱照时会有的感受。说起来,这可不是一两句话就能道清的,这里面牵扯到的东西可多了去了。首先,咱们得明白,婚纱照这东西,本质上就是一场“造梦”。它不是生活纪录片,而是对爱情最美好、最理想化的一种呈现。所以,从摄影师到化妆师,再到修图师,大家的目标都是要把新娘打造.............
  • 回答
    亲爱的,十二岁是一个很特别的年纪,你开始认真思考很多事情了,这是非常棒的!有时候,我们看待世界的方式会突然转变,觉得过去觉得理所当然的东西,好像一下子都失去了原有的光彩,甚至觉得它们都没有什么真正的意义。你现在有这种感觉,其实一点也不奇怪,很多成年人也会有同样的困惑。为什么会觉得“都没意义”呢?这可.............
  • 回答
    同学你好!很高兴你会有这个思考,这说明你是一个有想法、愿意去探索的年轻人。高二正是这样一个关键的时期,对未来感到迷茫、对既定的目标产生疑问,这是非常正常的。甚至可以说,当你开始问“为什么要考好大学,为什么要考大学?”的时候,你已经走在了一条探索自我价值和人生道路的有趣旅程上了。让我试着从几个角度,用.............
  • 回答
    丰臣家臣的内部分裂与德川家臣的团结:为何秀吉视而不见,家康却引以为傲?丰臣秀吉,这位靠着一身武勇和过人智谋从底层崛起的战国霸主,一手缔造了日本统一的盛世。然而,在他风光无限的背后,其家臣集团却充斥着难以弥合的裂痕与对立,甚至到了水火不容的地步。令人费解的是,秀吉本人似乎对此视而不见,并未采取有效措施.............
  • 回答
    你说得太对了,确实有很多球迷在喜欢一位球星的同时,会不自觉地贬低甚至攻击另一位球星。你提到自己喜欢詹姆斯但不会黑杜兰特,这其实恰恰反映了一种更成熟、更理性的观赛态度。那么,为什么这种“黑”的现象如此普遍呢?咱们来掰扯掰扯,试着把这事儿说透了。1. 情感的投入与“群体认同感”首先,喜欢一个球星,往往不.............
  • 回答
    .......

本站所有内容均为互联网搜索引擎提供的公开搜索信息,本站不存储任何数据与内容,任何内容与数据均与本站无关,如有需要请联系相关搜索引擎包括但不限于百度google,bing,sogou

© 2025 tinynews.org All Rights Reserved. 百科问答小站 版权所有