C++常量数组的编译时间较长



我正在用Node.js制作一个带有C++组件的游戏。此C++组件经常被调用(作为子进程(,并且是瓶颈。因此,我将其资产硬编码为 const 数组,以使其运行得更快。

但是,我注意到我的C++代码需要很长时间才能编译。以下是该问题的演示:

#include <iostream>
#include <vector>
#define d 3,
#define _ 999,
// an array holding some game assets
const std::vector<std::vector<std::vector<int>>> STRUCTURES {
{ // you should make 80 copies of this paragraph before benchmarking
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ d d d d d d d _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ d d d d d d d d d d d _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ d d d d d d d d d d d d d _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ d d d d d d d d d d d d d d _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ d d d d d d d d d d d d d d d _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ d d d d d d d d d d d d d d d d _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ d d d d d d d d d d d d d d d d _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d d _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d d _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d d d _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d d d _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d d d _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d d d _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d d d d _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d d d d _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d d d d _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d d d d _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d d d _ _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d d d _ _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d d _ _ _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d _ _ _ _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ d d d d d d d d d d d d d d d _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ d d d d d d d d d d d d d _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ d d d d d d d d d d d _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ d d d d d d d _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ },
},
};
int main(int argc, char **argv){
// prevent optimizer from ignoring the big array
std::cout << STRUCTURES.size() << std::endl;
return 0;
}

如果你重复中间段落80次,它的大小将与我的C++程序相当。我用g++ test.cpp -O3编译,编译需要 36 秒。我不明白为什么这么慢。我可以更改一些内容以使其编译得更快吗?

不使用动态分配有助于:

template <typename T, int a, int b, int c>
using sprites = std::array<std::array<std::array<T, c>, b>, a>;

但根本不分配必须更快。现在我不了解你,但我发现让初始化项正确并排列非常乏味(TM(,所以我们不要:

// an array holding some game assets
static constexpr char STRUCTURES[] {
// pos 0
"_____________________________________"
"_____________________________________"
"_____________________________________"
"_____________________________________"
"_________________________ddddddd_____"
"______________________ddddddddddd____"
"_____________________ddddddddddddd___"
"____________________dddddddddddddd___"
"___________________ddddddddddddddd___"
"__________________dddddddddddddddd___"
"_________________dddddddddddddddd____"
"________________ddddddddddddddddd____"
"_______________ddddddddddddddddd_____"
"______________ddddddddddddddddd______"
"____________dddddddddddddddddd_______"
"___________dddddddddddddddddd________"
"__________ddddddddddddddddddd________"
"_________ddddddddddddddddddd_________"
"________ddddddddddddddddddd__________"
"________ddddddddddddddddddd__________"
"_______dddddddddddddddddddd__________"
"______dddddddddddddddddddd___________"
"______dddddddddddddddddddd___________"
"______dddddddddddddddddddd___________"
"______ddddddddddddddddddd____________"
"______ddddddddddddddddddd____________"
"______dddddddddddddddddd_____________"
"______ddddddddddddddddd______________"
"_______ddddddddddddddd_______________"
"________ddddddddddddd________________"
"_________ddddddddddd_________________"
"___________ddddddd___________________"
"_____________________________________"
"_____________________________________"
"_____________________________________"
"_____________________________________"
"_____________________________________"
// pos 1
// ....
// ....
// ....
"_____________________________________"
"_____________________________________"
// pos 81
"_____________________________________"
"_____________________________________"
"_____________________________________"
"_____________________________________"
"_________________________ddddddd_____"
"______________________ddddddddddd____"
"_____________________ddddddddddddd___"
"____________________dddddddddddddd___"
"___________________ddddddddddddddd___"
"__________________dddddddddddddddd___"
"_________________dddddddddddddddd____"
"________________ddddddddddddddddd____"
"_______________ddddddddddddddddd_____"
"______________ddddddddddddddddd______"
"____________dddddddddddddddddd_______"
"___________dddddddddddddddddd________"
"__________ddddddddddddddddddd________"
"_________ddddddddddddddddddd_________"
"________ddddddddddddddddddd__________"
"________ddddddddddddddddddd__________"
"_______dddddddddddddddddddd__________"
"______dddddddddddddddddddd___________"
"______dddddddddddddddddddd___________"
"______dddddddddddddddddddd___________"
"______ddddddddddddddddddd____________"
"______ddddddddddddddddddd____________"
"______dddddddddddddddddd_____________"
"______ddddddddddddddddd______________"
"_______ddddddddddddddd_______________"
"________ddddddddddddd________________"
"_________ddddddddddd_________________"
"___________ddddddd___________________"
"_____________________________________"
"_____________________________________"
"_____________________________________"
"_____________________________________"
"_____________________________________"
};

朴素索引助手

现在,当然,你想要整数并将字符映射到某些值(在本例中为 3 和 999(。为此,我们可以使用一个朴素的索引助手:

struct Helper {
constexpr int operator()(int a, int b, int c) const {
switch (auto ch = STRUCTURES[a*37*37 + b*37 + c]) {
case 'd': return 999;
case '_': return 3;
}
return 0;
}
};

现在我们可以编写main来打印随机的"字形"、"精灵"或任何这些资源:

#include <iostream>
#include <iomanip>
int main() {
auto a = rand() % 81;
Helper index;
for (int b = 0; b < 37; ++b) {
for (int c = 0; c < 37; ++c)
std::cout << std::setw(4) << index(a, b, c);
std::cout << "n";
}
}

它打印(我有 81 倍相同的"图像"(:

3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3
3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3
3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3
3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3
3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3 999 999 999 999 999 999 999   3   3   3   3   3
3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3 999 999 999 999 999 999 999 999 999 999 999   3   3   3   3
3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3 999 999 999 999 999 999 999 999 999 999 999 999 999   3   3   3
3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3 999 999 999 999 999 999 999 999 999 999 999 999 999 999   3   3   3
3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999   3   3   3
3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999   3   3   3
3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999   3   3   3   3
3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999   3   3   3   3
3   3   3   3   3   3   3   3   3   3   3   3   3   3   3 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999   3   3   3   3   3
3   3   3   3   3   3   3   3   3   3   3   3   3   3 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999   3   3   3   3   3   3
3   3   3   3   3   3   3   3   3   3   3   3 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999   3   3   3   3   3   3   3
3   3   3   3   3   3   3   3   3   3   3 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999   3   3   3   3   3   3   3   3
3   3   3   3   3   3   3   3   3   3 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999   3   3   3   3   3   3   3   3
3   3   3   3   3   3   3   3   3 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999   3   3   3   3   3   3   3   3   3
3   3   3   3   3   3   3   3 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999   3   3   3   3   3   3   3   3   3   3
3   3   3   3   3   3   3   3 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999   3   3   3   3   3   3   3   3   3   3
3   3   3   3   3   3   3 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999   3   3   3   3   3   3   3   3   3   3
3   3   3   3   3   3 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999   3   3   3   3   3   3   3   3   3   3   3
3   3   3   3   3   3 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999   3   3   3   3   3   3   3   3   3   3   3
3   3   3   3   3   3 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999   3   3   3   3   3   3   3   3   3   3   3
3   3   3   3   3   3 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999   3   3   3   3   3   3   3   3   3   3   3   3
3   3   3   3   3   3 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999   3   3   3   3   3   3   3   3   3   3   3   3
3   3   3   3   3   3 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999   3   3   3   3   3   3   3   3   3   3   3   3   3
3   3   3   3   3   3 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999   3   3   3   3   3   3   3   3   3   3   3   3   3   3
3   3   3   3   3   3   3 999 999 999 999 999 999 999 999 999 999 999 999 999 999 999   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3
3   3   3   3   3   3   3   3 999 999 999 999 999 999 999 999 999 999 999 999 999   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3
3   3   3   3   3   3   3   3   3 999 999 999 999 999 999 999 999 999 999 999   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3
3   3   3   3   3   3   3   3   3   3   3 999 999 999 999 999 999 999   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3
3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3
3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3
3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3
3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3
3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3   3

非朴素索引助手:增强多阵列

更少的代码,更多的功能。现在,您可以使用.size()和范围

#include <boost/multi_array.hpp>
int main() {
constexpr std::array shape {81,37,37};
boost::const_multi_array_ref<char, 3> view(STRUCTURES, shape);
auto const& sprite = view[rand() % view.size()];
for (auto const& row : sprite) {
for (auto const& cell : row)
printf("%4d", (cell=='d'? 999 : 3));
putchar('n');
}
}

完整演示现场

  • 朴素索引Helper版本:Live On Coliru

    编译:(关于大肠杆菌!

    real    0m0.562s
    user    0m0.432s
    sys 0m0.124s
    

    运行时(在科利鲁!

    real    0m0.005s
    user    0m0.000s
    sys 0m0.004s
    
  • Boost Multi-Array 版本:编译器资源管理器/Coliru

在我的系统上,可执行文件大小为 118k (GCC( 或 119k(clang((两种方法(。

正如Barmar和Sam Varshavchik所建议的那样,解决方案是避免使用std::vector。

向量太多,优化器需要花费大量时间来处理。 可以使用 std::array 代替。对于此示例,这意味着:

#include <iostream>
#include <vector>
#include <array>
#define d 3,
#define _ 999,
// an array holding some game assets
const std::vector<std::array<std::array<int,37>,37>> STRUCTURES {
{{ // you should make 80 copies of this paragraph before benchmarking
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ d d d d d d d _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ d d d d d d d d d d d _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ d d d d d d d d d d d d d _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ d d d d d d d d d d d d d d _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ d d d d d d d d d d d d d d d _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ d d d d d d d d d d d d d d d d _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ d d d d d d d d d d d d d d d d _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d d _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d d _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d d d _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d d d _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d d d _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d d d _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d d d d _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d d d d _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d d d d _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d d d d _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d d d _ _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d d d _ _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d d _ _ _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ d d d d d d d d d d d d d d d d d _ _ _ _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ d d d d d d d d d d d d d d d _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ d d d d d d d d d d d d d _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ d d d d d d d d d d d _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ d d d d d d d _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ },
}},
};
int main(int argc, char **argv){
// prevent optimizer from ignoring the big array
std::cout << STRUCTURES.size() << std::endl;
return 0;
}

请注意,我仍然使用单个 std::vector 作为最外层的维度。这在编译时不会带来很大的开销。

相关内容

  • 没有找到相关文章

最新更新