沧州三亚菏泽经济预测自然
投稿投诉
自然科学
知识物理
化学生物
地理解释
预测理解
本质社会
人类现象
行为研究
经济政治
心理结构
关系指导
人文遗产
菏泽德阳
山西湖州
宝鸡上海
茂名内江
三亚信阳
长春北海
西安安徽
黄石烟台
沧州湛江
肇庆鹤壁
六安韶关
成都钦州

我用Rust改写了自己的C项目这两个语言都很折磨人!

7月19日 红朱砂投稿
  作者Strager
  译者马可薇
  策划褚杏娟
  C漫长的构建时间可谓臭名昭著,编程圈的我的代码在编译只是个段子,但C让这个段子长盛不衰。
  谷歌Chromium规模的项目在新硬件上的构建时间长达一小时,而在老硬件上的构建时间更是达到了六个小时。虽然也有海量的调整方案能加速构建速度,还有不少削减构建内容但极易出错的捷径供人选择,再加上数千美元的云计算能力,Chromium的构建时间仍是接近十分钟。这点我完全无法接受,人们每天都是怎么干活的啊?
  有人说Rust也是一样,构建时间同样令人头疼。但事实就是如此,还是这仅仅是一种反Rust的宣传手段?在构建时间方面Rust和C究竟谁能更胜一筹呢?
  构建速度和运行时性能对我来说非常重要。构建测试的周期越短,我编程就越高效、越快乐。我会不遗余力地让我的软件速度更快,让我的客户也越快乐。因此,我决定亲自试试Rust的构建速度到底怎么样,计划如下:
  找一个C项目把项目中的一部分单独拿出来逐行将C代码重写为Rust优化C和Rust项目的构建对比两个项目的构建测试时间
  我的猜想如下(有理有据的猜测,但不是结论):
  Rust的代码行数比C少。C中多数函数和方法都需要声明两次:一次在header里,一次在实现文件里。但Rust不需要,因此代码行数会更少C的完整构建时间比Rust长(Rust更胜一筹)。在每个。cpp文件里,都需要重新编译一次C的include功能和模板,虽然都是并行运行,但并行不等于完美。Rust的增量构建时间比C长(C更胜一筹)。Rust一个crate(独立可编译单元)一编译,但C是按文件编译。因此代码每次变动,Rust要读取的比C多。
  对此,大家怎么看呢?我在推特上的投票结果如下:
  42的人认为C会赢,35同意看情况,另外17的则觉得Rust会让我们大吃一惊。
  那么结果到底如何呢?下面让我们进入正题。
  编写C和Rust的测试对象找个项目
  考虑到我未来一个月都要花在重写代码上,什么样的代码最合适?我认为得满足以下几点:
  很少或不用第三方依赖(标准库可以使用);能在Linux和macOS上运行(我不怎么管Windows上的构建时间);大量测试套组(不然我没法确定Rust代码的正确性);FFI(外部函数接口)、指针、标准或自定义容器、功能类和函数、IO、并发、泛型、宏、SIMD(单指令多数据流)、继承等等,多少都有使用。
  其实答案也很简单,直接找我前几年一直在做的项目就行。我用的是一个JavaScript词法分析器,quicklintjs项目。
  quicklintjs的吉祥物Dusty
  截取C代码
  quicklintjs项目中C部分的代码行数超过10万,要把这些全改成Rust得花上我半年时间,不如只关注JavaScript词法分析部分,其中涉及项目中的:
  诊断系统翻译系统(用于诊断)各种内存分配器和容器(如bump分配器、适用于SIMD的字符串)各种功能类函数(如UTF8解码器、SIMD内在包装器)测试的辅助代码(如自定义断言宏)C的API
  可惜这部分代码里不涉及并发或IO,我测试不了Rust里asyncawait的编译时间开销,但这只是quicklintjs项目里的一小部分,所以我还不用太担心。
  我首先把所有的C代码都复制到新项目里,然后删掉已知与词法分析无关的部分,比如分析器和LSP服务器。我甚至一不小心删多了代码,最后不得不重新把这些代码添了回去。在我不断截代码的过程中,C的测试一直保持了通过状态。
  在彻底将quicklintjs项目中涉及词法分析的部分全截出来之后,项目中C的代码大约有1。7万行。
  C代码行数
  源码
  9。3k
  测试
  7。3k
  总计
  16。6k
  dep:GoogleTest
  69。7k
  重写代码
  至于要怎么重写这上千行的C代码,我选择按部就班:
  找一个适合转换的模块;复制黏贴代码、测试、搜索替换并修改部分语法、继续运行cargo(Rust的构建系统和包管理器)测试直到构建测测试都通过;如果这个模块依赖另一个模块,那就找到被依赖的模块,继续进行第二步,然后再回到现在这个模块;如果还有模块没转换,再回到第一步。
  主要影响Rust和C构建时间的问题在于,C的诊断系统是通过大量代码生成、宏、constexpr(常量表达式)实现的,而我在重写Rust版时,则用了代码生成、proc宏、普通宏以及一点点const实现。传闻proc宏速度很慢,也有说是因为代码质量太差导致的proc宏速度慢。希望我写的proc宏还可以(祈祷~)。
  我写完才发现,原来Rust项目比C项目还要大,Rust代码17。1k行,而C只有16。6k行。
  C代码行数
  Rust代码行数
  行数差
  源码
  9。3k
  9。5k
  0。2k(1。6)
  测试
  7。3k
  7。6k
  0。3k(4。3)
  总数
  16。6k
  17。1k
  0。4k(2。7)
  dep:GoogleTest
  69。7k
  dep:autocfg
  0。6k
  dep:lazystatic
  0。4k
  dep:libc
  88。6k
  dep:memoffset
  0。6k
  优化Rust构建
  构建时间很重要,因为我在截取C代码之前就已经做好了C项目构建时间的优化,所以我现在只需要对Rust项目的构建时间做同样的优化即可。以下是我觉得可能会优化Rust构建时间的条目:
  更快的链接器Cranelift后端编译器和链接器标志工作区与测试布局区分最小化依赖功能cargonextest使用PGO自定义工具链
  更快的链接器
  我第一步要做的是分析构建,我用的是Zselfprofilerustc标志。在这个标志所生成的两个文件里,其中一个文件中的runlinker阶段颇为突出:
  条目
  本身时间
  全部时间占比
  runlinker
  129。20ms
  60。326
  LLVMmodulecodegenemitobj
  23。58ms
  11。009
  LLVMpasses
  13。63ms
  6。365
  第一轮Zselfprofile结果
  之前我通过向Mold链接器的转换成功优化了C的构建时间,那这套对Rust能否行得通?
  Linux:链接器性能几乎一致。(数据越小越好)
  可惜,Linux上虽然确实有提升,但效果不明显。那macOS上的优化又表现如何?在macOS上默认链接器的替代品有两种,lld和zld,效果如下:
  macOS:链接器性能几乎不变。(数据越小越好)
  可以看出,macOS上替换默认链接器的效果同样不明显,我怀疑这可能是因为Linux和macOS上的默认链接器对我的小项目而言已经做到了最好,这些优化后的链接器(Mold、lld、zld)在大型项目上效果非常好。
  Cranelift后端
  让我们再回到Zselfprofile的另一篇报告上,LLVMmodulecodegenemitobj和LLVMpasses阶段颇为突出:
  条目
  自身时间
  全部时间占比
  LLVMmodulecodegenemitobj
  171。83ms
  24。274
  typeck
  57。50ms
  8。123
  evaltoallocationraw
  54。56ms
  7。708
  LLVMpasses
  50。03ms
  7。068
  codegenmodule
  40。58ms
  5。733
  mirborrowck
  36。94ms
  5。218
  Zselfprofile的第二轮结果
  传闻可以把rustc的后端从LLVM换成Cranelift,于是我又用rustcCranelift后端重新构建了一遍,Zselfprofile结果看起来不错:
  条目
  自身时间
  全部时间占比
  definefunction
  69。21ms
  12。307
  typeck
  57。94ms
  10。303
  evaltoallocationraw
  55。77ms
  9。917
  mirborrowck
  33。44ms
  6。657
  使用Cranelife的Zselfprofile第二轮结果
  可惜,在实际的构建中Cranelife比LLVM慢。
  Rust后端:默认LLVM比Cranelift强。(测试于Linux,数据越小越好)
  2023年1月7日更新:rustc的Cranelift后端维护者bjorn3帮我看了下为什么Cranelift在我的项目上效果不佳:可能是rustup的开销导致的。如果绕过这部分Cranelife效果可能会有提升,上图中的结果没有采用任何措施。
  编译器和链接器标志
  编译器里有一堆可以加快(或减缓)构建速度的选项,让我们一一试过:
  Zsharegenericsy(rustc)(Nightlyonly)ClinkargsWl,s(rustc)debugfalse(Cargo)debugassertionsfalse(Cargo)incrementaltrue且incrementalfalse(Cargo)overflowchecksfalse(Cargo)panicabort(Cargo)lib。doctestfalse(Cargo)lib。testfalse(Cargo)
  rustc标志:快速构建优于调试构建。(测试于Linux,数据越小越好)
  注:图中的quick,Zsharegenericsy与quick,incrementaltrue且启用Zsharegenericsy标志相等同,其余柱状图没有标识Zsharegenericsy是因为没有启用该标志,后者意味着需要nightlyrust编译器。
  上图中使用的多数选项都有文档可查,但我还没找到有人写过加s的链接。子命令s将包括Rust标准库静态链接在内的所有调试信息全部剥离,让链接器做更少的工作,从而减少链接时间。
  工作区与测试布局
  在文件的物理位置问题上,Rust和Cargo都提供了部分灵活性。对我的项目而言,以下是三种合理布局:
  理论上来说,如果我们把代码拆成多个crate,cargo就可以并行化rustc的调用。鉴于我的Linux机器上有一个32线程的CPU,macOS机器上有一个10线程的CPU,并行化应该可以降低构建时间。
  对一个crate而言,Rust项目中的测试有很多可运行的地方:
  由于依赖周期的存在,我没办法做源码文件内的测试这个布局的基准,但其他布局组合里我都做了基准:
  Rust完整构建:工作区布局最快。(测试于Linux,数据越小越好)
  Rust增量构建:最佳布局不明。(测试于Linux,数据越小越好)
  工作区设置中,无论是分成多个可执行测试(manytestexes),还是合并成一个可执行测试,似乎都能斩获头筹。所以后续我们还是按照工作区多个可执行文件的配置吧。最小化依赖功能
  多个crate的拆分支持可选功能,而部分可选功能都是默认启用的,具体功能可以通过cargotree命令查看:
  让我们把crate之一,libc中的std功能关掉,测试后再看看构建时间有没有变化。
  Cargo。toml〔dependencies〕libc{version0。2。138,defaultfeaturesfalse}libc{version0。2。138}
  关掉libc功能后没有任何变化。(测试于Linux,数据越小越好)
  构建时间没有任何变化,有可能std功能实际没什么大影响。不管怎么说,让我们进入下一个环节。
  cargonextest
  作为一款据说比cargo测试快60的工具,cargonextest对于我这个代码中44都是测试的项目来说非常合适。让我们来对比下构建和测试时间:
  Linux:cargonextest减慢了测试速度。(数据越小越好)
  在我的Linux机器上,cargonextest帮了倒忙,虽然输出不错,不过
  示例cargonextest测试输出:PASS〔0。002s〕cppvsrust::testlocalenomatchPASS〔0。002s〕cppvsrust::testoffsetoffieldshavedifferentoffsetsPASS〔0。002s〕cppvsrust::testoffsetofmatchesmemoffsetforprimitivefieldsPASS〔0。002s〕cppvsrust::testpaddedstringassliceexcludespaddingbytesPASS〔0。002s〕cppvsrust::testoffsetofmatchesmemoffsetforreferencefieldsPASS〔0。004s〕cppvsrust::testlinkedvectorpushseven
  那macOS上怎么说?
  macOS:cargonextest加快了构建测试。(数据越小越好)
  在我的MacBookpro上,cargonextest确实提高了构建测试的速度。但为什么Linux上没有呢?难道是和硬件有关?
  在下面测试中,我会在macOS上使用cargonextest,但Linux上的测试不用。
  使用PGO自定义工具链
  我发现C编译器的构建如果用配置文件引导的优化(PGO,也称作FDO),会有明显的性能提升。因此,让我们试试用PGO优化Rust工具链的同时,也用LLVMBOLT加上Ctargetcpunative进一步优化rustc。
  Rust工具链:自定义工具链是最快的。(测试于Linux,数据越小越好)
  如果你好奇的话,可以看看这段工具链构建脚本。可能不适用于你的机器,但只要我能运行就行:https:github。comquicklintcppvsrustblob953429a4d92923ec030301e5b00face1c13bb92btoolsbuildtoolchains。sh
  与C编译器相比,通过rustup发布的Rust工具链似乎已经是优化完成的结果。PGO加上BOLT的组合只带来了不到10的性能提升。但有提升就是好的,所以在后续与C的竞争中我们会继续使用这个速度最快的工具链。
  我第一次搭建的Rust自定义工具链比Nightly还要慢2,我在Rustconfig。toml的各种选项中反复调整,不断交叉检查Rust的CI构建脚本以及我自己的脚本,最终在好几天的挣扎后才让这二者性能持平。在我最终润色这篇文章时,我进行了rustup更新,拉取git项目,并重头又建了一遍工具链。结果这次我的自定义工具链速度更快了!有可能是我在Rust仓库里提交错了代码
  优化C构建
  在最初的C项目quicklintjs中,我已经用常见的手段优化了编译时间,比如用PCH、禁用异常和RTTI、调整编译标志、删除非必要include、将代码从头中移出、外置模板实例等方法。但此外还有一些C编译器和链接器我没试过,在我们进入C和Rust的对比之前,先从这些里面挑出最适合我们的。
  Linux:自定义Clang是最快的工具链。(数据越小越好)
  很明显,Linux上的GCC是个特例,而Clang的表现则要好上很多。我自定义构建的Clang(和Rust工具链一样,也是用PGO和BOLT构建的)相较于Ubuntu的Clang,显著优化了构建时间,而libstdc的构建略快于平均libc的速度。
  那我的自定义Clang加上libstdc在C和Rust的对比中表现如何呢?
  macOS:Xcode是最快的工具链。(数据越小越好)
  在macOS上,搭配Xcode的Clang工具链似乎要比LLVM网站上的Clang工具链优化得更好。
  C20模块
  我的C代码用的是include,但如果用C20中新增加的import又会怎么样呢?C20的模块是不是理论上来说应该会让编译速度超级快?
  我在项目了尝试过C20模块,但直到2023年的1月3日,Linux上的CMake模块支持过于实验性质了,我甚至连helloworld都没跑起来。
  或许2023年中C20模块会大放异彩,对于我这种超级在意构建时间的人来说,真是这样就太好了。但目前为止,我还是继续用经典C的include和Rust做对比吧。
  对比C和Rust的构建时间
  通过把C项目改写成Rust,并尽可能地优化Rust的构建时间后,问题来了:C和Rust究竟谁更快呢?
  很可惜,答案是看情况!
  Linux:Rust部分情况下构建速度超越C。(数据越小越好)
  在我的Linux机器上,部分情况下Rust的构建速度确实优于C,但也有速度持平或逊于C的情况。在增量lex的基准上,我们修改了大量源码,Clang比rustc速度快,但在其他增量基准上,rustc又会反超Clang。
  macOS:C构建速度通常快于Rust。(数据越小越好)
  但我的macOS机器上情况却截然不同。C的构建速度常常快上Rust许多。在增量测试utf8的基准,我们修改中等数量测试文件,rustc编译速度会略微超过Clang,但在包括全量构建等其他基准上,Clang很明显效果要更好。
  超过17k行代码
  我基准测试的项目只有17k行代码,算是小型项目,那么对超过10万行代码的大型项目来说,又是什么情况呢?
  我把最大的模块,也就是词法分析器的代码复制粘贴了8、16以及24遍,分别用来测试。因为我的基准里也包括了运行测试的时间,我觉得构建时间即使是对于那些能瞬间构建完的项目,也应该会线性增长。
  C代码行数
  Rust代码行数
  1x
  16。6k
  17。7k
  8x
  52。3k(215)
  43。7k(156)
  16x
  93。1k(460)
  74。0k(334)
  24x
  133。8k(705)
  104。4k(512)
  倍数扩大后C完整构建优于Rust。(测试于Linux,数据越小越好)
  倍数扩大后C增量构建优于Rust。(测试于Linux,数据越小越好)
  Rust和Clang确实都是线性扩大,这点很好。
  正如预期中一样,修改C的头文件,也就是增量diagtype会大幅影响构建时间。而由于Mold链接器的存在,其他增量基准中构建时间的扩展系数很低。
  Rust构建的扩展性让我很失望,即使只是增量utf8测试的基准,无关文件的加入也不应该让它的构建时间如此受影响。测试所用的crate布局时工作区且多个可执行测试,因此utf8测试应该能独立编译可执行文件。结论
  编译时间对Rust而言算是问题吗?答案是肯定的。虽然也有一些可以加快编译速度的提示和技巧,但却没有效果非常显著的数量级改进,这让我在开发Rust时非常高兴。
  Rust的编译时间和C相比呢?确实也很糟。至少对我的编码风格来说,Rust在大型项目上开发的编译时间甚至更加远比C还要糟糕。
  再回过头看看我当初的假设,几乎全军覆没:
  Rust改写版代码行数比C多;在全量构建上,C相比Rust在1。7万行代码上构建时间相似,在10万行代码上构建时间要少;在增量构建上,Rust相比C在部分情况构建时间要短,在1。7万行上构建时间要长,在10万行代码上构建时间甚至更长。
  我不爽吗?确实。在改写过程中,我不断学习着Rust相关的知识,比如procmarco能替代三个不同代码生成器,简化构建流水线,让新开发者们日子更好过。但我完全不想念头文件,以及Rust的工具类真的很好用,特别是Cargo、rustup以及miri。
  但我决定不把quicklintjs项目中剩下的代码也改成Rust,但如果Rust的构建时间能有明显优化,或许我会改变主意。当然,前提是我还没被Zig迷走心神。
  附注源码
  删减后的C项目源码、移植版Rust(包括不同的项目布局)、代码生成脚本和基准测试脚本、GPL3。0及以上。
  Linux机器
  名称:strapurp
  CPU:AMDRyzen95950X(PBO;stockclocks)(32threads)(x8664)
  RAM:G。SKILLF44000C1916GTZR2x16GiB(overclockedto3800MTs)
  操作系统:LinuxMint21。1
  内核:Linuxstrapurp5。15。056generic62UbuntuSMPTueNov2219:54:14UTC2022x8664x8664x8664GNULinux
  Linux性能治理器:schedutil
  CMake:版本3。19。1
  Ninja:版本1。10。2
  GCC:版本12。1。02ubuntu122。04
  Clang(Ubuntu):版本14。0。01ubuntu1
  Clang(自定义):版本15。0。6(R代码提交3dfd4d93fa013e1c0578d3ceac5c8f4ebba4b6ec)
  libstdcforClang:版本11。3。01ubuntu122。04
  Rust稳定版:1。66。0(69f9c33d720221212)
  RustNightly:版本1。68。0nightly(c7572670a20230103)
  Rust(自定义):版本1。68。0dev(c7572670a20230103)
  Mold:版本0。9。3(ec3319b37f653dccfa4d1a859a5c687565ab722d)
  binutils:版本2。38
  macOS机器
  名称:strammer
  CPU:AppleM1Max(10threads)(AArch64)
  RAM:Apple64GiB
  操作系统:macOSMonterey12。6
  CMake:版本3。19。1
  Ninja:版本1。10。2
  XcodeClang:Appleclang版本14。0。0(clang1400。0。29。202)(Xcode14。2)
  Clang15:版本15。0。6(LLVM。orgwebsite)
  Rust稳定版:1。66。0(69f9c33d720221212)
  RustNightly:版本1。68。0nightly(c7572670a20230103)
  Rust(自定义):版本1。68。0dev(c7572670a20230103)
  lld:版本15。0。6
  zld:代码提交d50a975a5fe6576ba0fd2863897c6d016eaeac41
  基准
  用deps的构建和测试
  C:cmakeSbuildB。GNinjaninjaCbuildquicklintjstestbuildtestquicklintjstest计时
  Rust:cargofetch未计时,再用cargotest计时
  不用deps的构建和测试
  C:cmakeSbuildB。GNinjaninjaCbuildgmockgmockmaingtest未计时,再用ninjaCbuildquicklintjstestbuildtestquicklintjstest计时
  Rust:cargobuildpackagelazystaticpackagelibcpackagememoffset未计时,再用cargotest计时
  增量diagtypes
  C:构建和测试未计时,随后修改diagnostictypes。h,再用ninjaCbuildquicklintjstestbuildtestquicklintjstest
  Rust:构建和测试未计时,修改diagnostictypes。rs后,cargotest
  增量lex
  同增量diagtypes,但使用lex。cpplex。rs
  增量utf8测试
  同增量,但使用testutf8。cpptestutf8。rs
  每个可执行基准均采用12个样本,弃置前两个,基准仅显示最后十个样本的平均性能。误差区间展示最小与最大样本间区别。
  原文链接:
  https:quicklintjs。comblogcppvsrustbuildtimes
投诉 评论 转载

新疆大学济南大学青岛科技大学山东科技大学青岛大学,这几所大学下面先对五所院校办学实力进行一下比较:新疆大学新疆大学,位于新疆维吾尔自治区首府乌鲁木齐市。是新疆维吾尔自治区属高校,是211高校,是双一流B类高校,是省部共建高校……怎样才能考上清华大学?近几年身边有几个学生上了清北,也分析过他们的一路走来的经验,总体而言,对普通家庭的学生来说,能否提高学习成绩取决于家庭和个人努力,能否上清北则要看人品。毕竟,清北就那么几个名额……我用Rust改写了自己的C项目这两个语言都很折磨人!作者Strager译者马可薇策划褚杏娟C漫长的构建时间可谓臭名昭著,编程圈的我的代码在编译只是个段子,但C让这个段子长盛不衰。谷歌Chromium规模的……路边摊的炸香肠,到底是什么肉做的?实测6款,结果很颠覆无论有多少新奇的小吃出现,炸淀粉肠都牢牢占据着路边摊王者的地位,经久不衰。小时候,最快乐的事情是吃一根校门口小摊上的淀粉肠;长大后,不过是校门口换成了公司楼下。今年……未来病毒会不会变得传染性更强致病性更强?中疾控回应央视网消息:2月9日,国务院联防联控机制就重点人群、重点机构、重点场所疫情防控情况举行发布会。会上,中国疾控中心流行病学首席专家吴尊友表示,新冠病毒的变异速度非常快,从全……智能手表与血氧仪监测结果有差异,使用时要注意这些来源:上海网络辟谣近日,血氧仪成为紧俏货,有测量血氧功能的智能手表、手环等也备受消费者追捧,网络上还出现了血氧监测网站、小程序等。但有人疑惑,血氧仪是医疗器械,智能……曼联残阵出征,巴塞罗那坐镇主场有优势文羊城晚报全媒体记者刘毅欧联杯附加赛首回合2月17日上演豪门对决,西甲领头羊巴塞罗那主场迎战曼联,两回合胜者进入16强。曾几何时,巴萨和曼联是欧冠决赛对手。在200……深圳创新人才培养机制托起幸福夕阳红人才是高质量发展的第一资源。为有效破解养老服务人才专业性不强、流动性大、结构不合理等发展瓶颈,近年来,深圳市紧抓双区建设、双改示范重大历史机遇,探索构建了一条政校行企四方联动、……什么是山河四省梗,为什么曾经重要的的山河四省沦落于此?山河四省是指位于中国北方的河北、河南、山东、山西四省。这个名字来自这样一个事实,即其中两个省以山(山)的汉字开头,而另外两个省以河字开头,又由于同样经济发展水平不太好。这四个省……津台民众线上相聚赏非遗品民俗云拜年送祝福活动现场(图片来源:天津市南开区台办)中国台湾网2月10日讯农历兔年伊始,带着对亲朋好友的新春祝福和对美好未来的热切期盼,天津市南开区与台湾省新竹县再次线上相聚,于2月7……近1。6万次!基金经理已出门几天了!机构忙调研,这一领域最受点蓝字关注,不迷路调研是机构投资者获取上市公司最新信息的重要方式之一。2023年来,随着A股行情的好转,机构调研热情明显提升。数据显示,截至目前,已有超500家A股上市公……关注丨2023年民营企业金融支持力度将加大图片来源摄图网中国经济时报记者王小霞2023年,民营企业的金融服务力度将进一步加大。中央经济工作会议要求,从政策和舆论上鼓励支持民营经济和民营企业发展壮大。中国人民……
女性内分泌失调怎么办这个方法可以调理驿通科技携ETC助手二代ETC亮相服贸会不只是情人节!盘点七夕的那些传统习俗和施华洛世奇区别高考601分女孩遇害,凶手身份曝光挤过独木桥,却逃不过杀人犯军营硬汉,开始你的展示小暑至农事忙各地不误农时抓紧进行夏收夏种夏管工作脖子和腋下的小肉粒是什么?能不能用手抠掉呢?早看早了解股票攻击线是什么样的五日均线怎么看图解法台土房哥叫嚣一枚雄三可击沉海南舰,网友无脑绿粉产后吃的为什么要清淡为何唐三只解释十万年魂环来自邪恶魂兽?因为他还要再杀万年魂兽

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找