精华内容
下载资源
问答
  • Tips for Optimizing C/C++ Code》译文

    千次阅读 2014-05-19 23:05:07
    前不久在微博上看到一篇很好的短文讲如何对C/C++进行性能优化,虽然其面向的领域是图形学中的光线跟踪,但是还是具有普遍的意义,将其翻译成中文,希望对大家写高质量代码有帮助。 1. 牢记阿姆达尔定律:加速比=...

    前不久在微博上看到一篇很好的短文讲如何对C/C++进行性能优化,虽然其面向的领域是图形学中的光线跟踪,但是还是具有普遍的意义,将其翻译成中文,希望对大家写高质量代码有帮助。

    1.     牢记阿姆达尔定律:加速比==

    • 其中表示函数func运行时间占总时间的百分比,表示对该函数加速获得的加速比。
    • 例如,你优化一个函数TriangleIntersect(),该函数的运行时间占总时间的40%,优化之后运行时间缩短一半,则整个代码会获得25%的性能提升
    • 这个公式告诉我们不常用的代码(例如场景加载程序)没有必要优化(或者完全不用优化)。
    • 一句话总结“使常用代码更快,不常用代码正确”。

    2.     在保证正确性的前提下去优化代码!

    • 但是这不意味着你需要首先耗费8周的时间去实现一个完整的光线跟踪代码,然后再花费另外的8周去优化!
    • 代码优化要分成多个步骤。
    • 首先编写正确的代码,然后寻找被经常调用的函数,对其进行优化。
    • 最后寻找整个代码的瓶颈,通过优化或者修改算法去除瓶颈。通常算法的改进可能会使代码的瓶颈转移—甚至会转移到你意想不到的函数中。由于这个原因的存在,我们需要对经常访问的所有函数进行显式优化。

    3.     我认识的代码高手都自称他们优化代码的时间是写代码时间的两倍。

    4.     跳转/分支操作很耗时。如果可能尽可能的少用它们。

    • 函数调用除了栈上内存的操作之外,还包括两个跳转操作。
    • 尽量用迭代而不是递归。
    • 对代码长度较短的函数要将其设置为内联函数以减小函数调用的开销。
    • 将循环放在函数内部(例如,代码:for(i=0;i<100;i++)DoSomething(); 可以修改为DoSomething(){for(i=0;i<100;i++){…}},以此可以减少函数调用的次数)。
    • 具有很长if…else if…else if…else if…链的代码在判断后面的条件时需要非常多的跳转操作。如果可能,将其改为switch代码结构,因为switch通过查询一个跳转表实现了单步跳转。如果不能改为switch结构,要将最可能被访问的判断条件放在条件链的最前面。

    5.     仔细考虑数组下标的顺序。

    • 二维或者更高维的数组在内存中实际上还是一维形式的存在。这就说明(针对C/C++数组)元素array[i][j]array[i][j+1]在内存中位置相邻,但是元素array[i][j]array[i+1][j]却可以相差任意个位置。
    • 如果我们在访问内存中数组的时候是以一种近似线性的顺序实现的,代码通常会获得非常明显的加速(有时会达到一个数量级,甚至更高)!
    • 现在的CPU在从内存加载数据到缓存时,它不会只加载要访问的一个数据,而是会将一块内存(cache line)都加载到缓存中。这意味着当元素array[i][j]在缓存中时,array[i][j+1]也很有可能在缓存中,但是array[i+1][j]却依旧在内存中。

    6.     考虑指令级并行。

    • 尽管目前还有很多程序是单线程执行的,但是现在的CPU早就在单核上实现了并行。这就意味着在单核上可能会同时执行4个浮点乘法,等待4个内存请求和即将到来的分支操作。
    • 为了充分利用指令级并行,代码块(跳转指令之间)需要有充足的独立指令(指令之间没有相关性:数据相关、控制相关和名字相关)。
    • 可以考虑循环展开。
    • 考虑内联函数。

    7.     避免使用或者减少局部变量的数量。

    • 局部变量通常放在栈空间中。但是如果局部变量的个数足够少,它们可以被放在寄存器中。在这种情况下,函数可以获得比内存快得多的访问速度,同时也避免了栈空间的布局。
    • 但是,也不要为了减少局部变量的个数将它们全都变为全局变量。

    8.     减少函数的参数。

    • 和减少局部变量的原因一致—它们都放在栈中。

    9.     结构体按照引用而不是按照值传递。

    • 据我所知,光线跟踪代码中没有什么结构体需要按值传递(即使简单的向量,点和颜色等结构)。

    10.  如果函数不需要返回值,就不要定义返回值。

    11.  尽可能地避免类型强转。

    • 整型和浮点型指令操作通常在不同的寄存器中,所以类型强转意味着数据的复制。
    • 短整型(char和short)仍然需要一个完整的寄存器来存储。在存到内存中时,才再次转换成字节存储(不过是否需要强转还需要考虑空间耗费的因素,强转节省空间但是费时)。

    12.  声明C++对象变量的时候要各位仔细。

    • 使用对象的初始化而不是赋值操作(Color c(black);Color c; c=black;要快)。

    13.  将类的默认构造函数设计得尽量小。

    • 特别是那些很小但是经常被使用的类(如color,vector,point等)。
    • 默认构造函数经常会在你想不到的时候调用。
    • 使用构造函数初始化列表(使用Color::Color():r(0),g(0),b(0){},而不是Color::Color(){r=g=b=0;})。

    14.  尽可能使用移位操作>>和<<代替整数的乘除法。

    15.  在使用查表函数时要谨慎(光线跟踪专用)。

    • 很多人都建议查表使用预先计算的值来代替复杂的函数(例如三角函数)。但是在光线跟踪中,这通常没有必要。内存查找很耗时,这会抵消重新计算三角函数的时间(尤其是考虑到查表会破坏CPU的缓存结构时)。
    • 在其他场合下,查表通常会很有帮助。在GPU编程中,查表替代复杂操作是允许的。

    16.  对大多数类操作,使用+= ,-= , *= , and /=而不是+ , - , * , and /。

    • 简单操作是用来创建未命名或者临时中间对象的。
    • 例如:Vector v = Vector(1,0,0) +Vector(0,1,0) + Vector(0,0,1);创建了5个未命名、临时向量:Vector(1,0,0), Vector(0,1,0), Vector(0,0,1), Vector(1,0,0) +Vector(0,1,0),Vector(1,0,0) +Vector(0,1,0)+ Vector(0,0,1)。
    • 稍微长一点的代码:Vector v(1,0,0); v+=Vector(0,1,0); v+= Vector(0,0,1);仅创建了两个临时变量:Vector(0,1,0) andVector(0,0,1)。这会节约6次函数调用(3次构造函数和3次析构函数)。

    17.  对于基本数据类型采用+ ,- , *,/而不是+= , -= , *= , and /=。

    18.  推迟局部变量的声明。

    • 声明一个类对象需要一次函数调用(对构造函数的调用)。
    • 如果一个变量只在某个条件下使用,则只在真正需要的地方声明该变量。

    19.  对于对象(基本变量已被优化),使用前缀操作(++obj)代替后缀操作(obj++)。

    • 在光线跟踪中这不是一个问题。
    • 后缀操作会带来一次对象的复制(这需要额外调用一次构造函数和析构函数),但是前缀操作不需要临时的复制。

    20.  使用模板的时候要小心。

    • 不同实例化的优化方法不同!
    • 标准模板类已经被优化得很彻底,但是还是避免使用它。
    • 为什么不用?这是因为如果我们自己实现某个算法,我们就会知道算法细节以及优化方式。
    • 更重要的是,我的经验告诉我在debug模式下编译包含STL的代码通常会很缓慢。这一般不是一个问题,除非你使用debug版本进行性能分析。你将会发现STL构造器,迭代器等会占用15%以上的运行时间,这将导致性能输出结果令人迷惑。

    21.  在计算的过程中避免动态内存分配。

    • 动态内存分配适合于存储场景和计算过程中不变的数据。
    • 然而,在大多数系统中,动态内存分配需要利用锁来控制分配器的访问。对于多线程应用,增加额外的处理器也可能会使性能下降,因为使用动态内存分配会导致线程不停地等待内存的分配和释放。
    • 即使是对单线程应用,在堆上分配内存也比在栈上分配内存更耗时。因为操作系统需要做一些计算来寻找合适大小的内存块。

    22.  寻找和利用可以优化系统缓存访问的一切信息。

    • 如果一个数据结构可以存放于单个cache line,则单次内存访问就可以将整个类加载到缓存中。
    • 确保你的数据结构对齐到cache line的边界(如果你的数据结构和cacheline都是128字节,但是结构体的第1个字节在第一个cache line中,剩余的127字节在第二个cache line中,那么性能还是会非常差)。

    23.  避免不必要的数据初始化。

    • 如果你需要初始化大块内存,请使用memset()

    24.  尝试循环的提前终止和函数的提前返回。

    • 考虑一条光线和一个三角形的交。合理的情况是光线通不过三角形。这就是需要优化的地方。
    • 如果你需要确定光线和三角平面的交,当光线-平面交的t值为负时你可以离开返回。这使你避免了求交过程中大约一半的质心计算。

    25.  在纸上简化方程。

    • 在很多方程中,其实有些项在某些情况下可以被约去。
    • 编译器不能发现方程的简化,但是你行。有时只是消除内部循环的一些耗时操作就可以抵上你在其他地方工作好几天的成果。

    26.  整数、浮点数在数学上的差异可能没有想象中大。

    • 在现代CPU中,浮点运算具有和整数运算相同的吞吐量。像光线跟踪这样的计算密集型应用,浮点操作和整数操作的差异非常小。所以,没有必要想方设法将操作转成整数操作。
    • 双精度浮点数操作可能比单精度慢,特别是在64位机器上。但是也可能会反过来。

    27.  考虑将运算表达式变形以减少耗时操作。

    • sqrt()操作应该尽量被避免,特别是通过平方操作也可以获得同样结果时。
    • 如果你需要频繁的进行除以x的操作,可以考虑首先计算,然后将结果乘以。这在向量归一化(3次除法)中会带来较大收益。但是最近我发现情况变得有点难以判断。不过,如果除法次数超过3次时,这种优化方法还是会带来较大的性能提升。
    • 如果你在执行一个循环,请把计算结果保持不变的运算提到循环外面完成。
    • 考虑是否可以增量计算一个变量(而不是每次都从头开始计算该变量)。


    展开全文
  • 先说个比较搞的事情,Google Chrome 的英文名字其实还不错(虽然会让人联想到Firefox 的 chrome 协议),但不知为何,中文语言包就硬生生地把它翻译成了“谷歌浏览器”…… 这……Google被翻译成谷歌已经实属郁闷了...

    googlechrome

    Hi, 大家好~ 好久没有发有营养的东西,今天就扔一篇最近热点的Google Chrome 浏览器的试用心得吧。

     

    先说个比较搞的事情,Google Chrome 的英文名字其实还不错(虽然会让人联想到Firefox 的 chrome 协议),但不知为何,中文语言包就硬生生地把它翻译成了“谷歌浏览器”…… 这……Google被翻译成谷歌已经实属郁闷了,这次干脆把Chrome几个字吃掉了,好硬的牙口=v=

     

    言归正传,还是以web前端开发者的角度来谈谈Google Chrome 吧。

     

    首先呢,google做了一件虽然看上去是普宣,但其实多少故意针对前端开发者的很smart宣传——大家请看——google chrome geek comic:

    googlecomic

    本物comic 网址:http://www.google.com/googlebooks/chrome/

    这种geek comic 其实是前端开发间很流行的一种艺术形式,算是很恰当的把技术和现代艺术结合了,所以看得懂这个的人,应该很有潜质做前端开发才对

     

    在Google Chrome 发布以前,流传着一些Google会自己开发浏览器内核的风闻。不过随着Chrome的发布,流言不攻自破。Chrome 的确是使用了Webkit 的内核,所以基本可以参照同类的Safari,连UA都是这样的:

    Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/525.13 (KHTML, like Gecko) Chrome/0.X.Y.Z Safari/525.13.

    所以初步测试,对于样式表的解析和javascript的执行,Chrome 与 Safari 类似度颇高:

    jeff-chrome jeff-safari

    左图为Chrome, 右图为Safari。可以看见,Safari 除了拥有自己的字体加强算法之外,其它的呈现和Chrome无异。(PS: 照片系老赵授权发布,请大家不要转载,要看的可以去这里保存,另外还有老赵超多的萌图雷图等你发现

    甚至两者都有相似的输入框高亮和改变textarea大小的功能:

    quicklogin_chrome quicklogin_safari

    连ACID3评分也差不多:(如果不了解ACID3,可以到这里看看100分是什么情况的)

    acid3_chrome acid3_safari

    好消息是,Chrome也会支持一些未来世代(?)的功能。还记得这个Canvas应用么?

    canvas_chrome

     

    所以至此,我们不必太担心hack对Chrome的影响,因为和Mac 的Safari 3.1 (自称是上最好的浏览器……Apple官网)使用同样的webkit core, 所以hack方面完全兼容——其实在这样令人省心的浏览器上,根本没必要用hack。如果真要使用的话,推荐用一些CSS3的伪类,比如:first-of-type。不过这样真的是完全没有必要的

    不过现在暂时还没有报导声称能使用CSS hack 区别Chrome 和Safari 3.1(理论上也不太可能会有)。对此我们以娱乐的心态持续关注中=v= (撒花

     

    最后顺便介绍一下Chrome 为前端开发者提供的一些小工具:

     

    首先是Web Inspector: 在页面上任何地方点右键,在上下文菜单里会有“审查元素”的选项。不过这词翻译的……审查

    contextmenu_chrome

    之后就会有一个类似于DOM inspector 的东东出现……感觉到有点像Opera的Dragonfly。请注意右下角的metrics:

    inspector

    另外,也支持 javascript console(有代码提示功能):

    inspector2

    以及网页下载速度分析的功能,支持按照时间轴,文件大小,单个文件查看:

    inspector3 inspector4 inspector5

    但是似乎还是不能查看一个文件详细的header信息,所以暂时还要借助Fiddler

     

    只能以命令行方式运作的 JavaScript Debugger:

    jsdebugger jsdebugger2

    只有最基本的功能……期待这块以后有所加强。完全可以和firebug 一样集成在DOM Inspector里嘛

     

    不过下面这个东西还是很好用的——一个内建的Task Manager

    taskmanager taskmanager2

    可以监测网页的性能,比windows 自带的task manager 精确多了,可以用来跑一些test case 来测试性能也不错

     

    基本就这些了,如果有些新的发现再向大家汇报哟~ 以上,大家下次见了哟~

     

    PS:上文部分技术规格来源于Google Chrome相关文档。

    转载于:https://www.cnblogs.com/ruxpinsp1/archive/2008/09/08/google-chrome-front-end-features.html

    展开全文
  • Keras中文手册

    2018-09-18 13:35:46
    1.x版本:现有keras.io文档的中文翻译,保持与官方文档的同步 2.x版本:完善所有【Tips】模块,澄清深度学习中的相关概念和Keras模块的使用方法 3.x版本:增加Keras相关模块的实现原理和部分细节,帮助用户更准确的...
  • 实际上,英文简历在样式和写作方法上与中文简历存在很多不同,如果仅仅是将中文简历翻译成英文,而不根据英文简历的特点做相应的处理,写出来的简历给人的感觉会很奇怪。看看这些小Tips~个人信息在英文简历中一般只...

    英文简历只是中文简历的翻译版本吗?

    NO!

    实际上,英文简历在样式和写作方法上与中文简历存在很多不同,如果仅仅是将中文简历翻译成英文,而不根据英文简历的特点做相应的处理,写出来的简历给人的感觉会很奇怪。

    看看这些小Tips~

    bf30c9e7f248fe590445322b5750803e.png

    个人信息

    在英文简历中一般只需要列出姓名、邮箱、联系地址、联系方式等基本信息。姓名部分可以直接用拼音来代替,写地址时要注意中英文表达的差别,英文地址是从小到大,且中间要用逗号隔开哦。

    经历

    在写经历时,有以下几个需要注意的地方:

    1. 在描述自己的经历时要采用“倒叙”的方式,即先写最近的工作经历,再写以往的工作经历(如果你还是学生,没有工作经历,可以写自己的实习经历或者项目经历)。

    2. 在描述工作经历时通常使用一般过去时,同时,要尽量少用完整的句子,不用I或者My开头的句子,多使用动词或名词结构来描述经历。

    3. 在描述自己的成就时应该用具体的数字表述清楚,尽量避免用many, much, great, several, a large number of 等较为含糊的说法。

    教育背景

    教育背景信息也要采用“倒叙”的方式来写,最近的学历信息要放在最前面。在教育背景信息中可以列出GPA,奖学金,发表的论文以及其他学术成就。

    还可以根据自己的情况增加其他模块,例如技能(skills)。

    学会参考模板

    要保证我们最后做出来的英文简历足够地道,最简单也最保险的方法是参考现有的英文简历模板,学习它们的样式和写作手法。

    c0624a00de546114851dbab24cc44a19.png67162bc7183158cecc5e9c3dc39288aa.png9753df850e2d5a794ef41e06548a4cfc.png80ebc553e496c8add50aa04154622e46.pngda9ece07aef4f0eb662bd7c37a6f7515.png5ebf2c90375b4cbf67474e58cbabb602.pnga49993518b6ede0fa2208c6e101ed061.png664ccf66ba2736831ce5b73c4958b4ee.png1937e8a06887c7cf7d7cbf79c044a5d3.gif

                 后台回复【wang】即可免费获取     

    739bc58ad389bb04514d6735f69b55ee.png

    感谢阅读

        TO  BE CONTINUE...

    bf30c9e7f248fe590445322b5750803e.png
    展开全文
  • 所以第二版的翻译也借鉴copy了第一版翻译:即,如果第二版中有和第一版相同的文字,则copy第一版的中文译本,觉得不妥的地方会稍加修改,剩下的不同的内容就自己翻译。这样做也是为读过第一版的老读者考虑——相同的...
  • Smarty中文手册 chm版

    2010-05-21 15:01:58
    Table of Contents [内容列表] Preface [序] I. Getting Started [开始] 1. What is Smarty? [什么是Smaty?] 2. Installation [安装] Requirements [安装] Basic Installation [基本安装...21. LIST 翻译人员列表
  • 本系列文章翻译自《50 Tips and Tricks for MongoDB Developers》,暂时没有找到中文版,反正自己最近也在深入学习mongodb,所以正好拿来翻译一下。...首先声明自己的英文水平不是太高,加之有些英文翻译成中文也找...

    本系列文章翻译自《50 Tips and Tricks for MongoDB Developers》,暂时没有找到中文版,反正自己最近也在深入学习mongodb,所以正好拿来翻译一下。一方面加强自己学习的效果,另一方面让大 家也一起来体验一下需要我们这些mongodb使用者需要注意的地方。

    首先声明自己的英文水平不是太高,加之有些英文翻译成中文也找不到合适的词来表达,所以在文章中可能会出现英文原词,或者说有些地方的翻译会有些生 硬,也就是说会出现直译的地方。翻译该书的主要目的是为大家学习探讨用的,如果有翻译不精准的地方,或者说有更加精准的翻译,还请大家指出,我会及时的更 正的,在此先谢过各位了。

    Tip#5.Embed "point-in-tme" data

    对某一时间点的数据采用嵌入式结构

    在Tip#1中提到的订单的例子,你不希望存储在订单中的产品信息随着继续的交易发生变化。有很多类似的数据,你需要一个购买时候的快照,这样的信息应该使用嵌入式结构。

    另外一个来自




    本文转自 virusswb 51CTO博客,原文链接http://blog.51cto.com/virusswb/795494,如需转载请自行联系原作者订单文档的例子是,地址,这属于某一时间点这种类型的数据。你不希望在用户更新了个人信息之后,过去的订单中的地址信息发生任何变化。

    展开全文
  • 本系列文章翻译自《50 Tips and Tricks for MongoDB Developers》,暂时没有找到中文版,反正自己最近也在深入学习mongodb,所以正好拿来翻译...首先声明自己的英文水平不是太高,加之有些英文翻译成中文也找不到...
  • 本系列文章翻译自《50 Tips and Tricks for MongoDB Developers》,暂时没有找到中文版,反正自己最近也在深入学习mongodb,所以正好拿来翻译...首先声明自己的英文水平不是太高,加之有些英文翻译成中文也找不到...
  • 本系列文章翻译自《50 Tips and Tricks for MongoDB Developers》,暂时没有找到中文版,反正自己最近也在深入学习mongodb,所以正好拿来翻译...首先声明自己的英文水平不是太高,加之有些英文翻译成中文也找不到...
  • 本系列文章翻译自《50 Tips and Tricks for MongoDB Developers》,暂时没有找到中文版,反正自己最近也在深入学习mongodb,所以正好拿来翻译...首先声明自己的英文水平不是太高,加之有些英文翻译成中文也找不到...
  • 本系列文章翻译自《50 Tips and Tricks for MongoDB Developers》,暂时没有找到中文版,反正自己最近也在深入学习mongodb,所以正好拿来翻译...首先声明自己的英文水平不是太高,加之有些英文翻译成中文也找不到...
  • 本系列文章翻译自《50 Tips and Tricks for MongoDB Developers》,暂时没有找到中文版,反正自己最近也在深入学习mongodb,所以正好拿来翻译...首先声明自己的英文水平不是太高,加之有些英文翻译成中文也找不到合...
  • 本系列文章翻译自《50 Tips and Tricks for MongoDB Developers》,暂时没有找到中文版,反正自己最近也在深入学习mongodb,所以正好拿来翻译...首先声明自己的英文水平不是太高,加之有些英文翻译成中文也找不到...
  • 本系列文章翻译自《50 Tips and Tricks for MongoDB Developers》,暂时没有找到中文版,反正自己最近也在深入学习mongodb,所以正好拿来翻译...首先声明自己的英文水平不是太高,加之有些英文翻译成中文也找不到...
  • 本系列文章翻译自《50 Tips and Tricks for MongoDB Developers》,暂时没有找到中文版,反正自己最近也在深入学习mongodb,所以正好拿来翻译...首先声明自己的英文水平不是太高,加之有些英文翻译成中文也找不到...
  • 本系列文章翻译自《50 Tips and Tricks for MongoDB Developers》,暂时没有找到中文版,反正自己最近也在深入学习mongodb,所以正好拿来翻译...首先声明自己的英文水平不是太高,加之有些英文翻译成中文也找不到...
  • 本系列文章翻译自《50 Tips and Tricks for MongoDB Developers》,暂时没有找到中文版,反正自己最近也在深入学习mongodb,所以正好拿来翻译...首先声明自己的英文水平不是太高,加之有些英文翻译成中文也找不到...
  • 本系列文章翻译自《50 Tips and Tricks for MongoDB Developers》,暂时没有找到中文版,反正自己最近也在深入学习mongodb,所以正好拿来翻译...首先声明自己的英文水平不是太高,加之有些英文翻译成中文也找不到...
  • 本系列文章翻译自《50 Tips and Tricks for MongoDB Developers》,暂时没有找到中文版,反正自己最近也在深入学习mongodb,所以正好拿来翻译...首先声明自己的英文水平不是太高,加之有些英文翻译成中文也找不到...
  • 本系列文章翻译自《50 Tips and Tricks for MongoDB Developers》,暂时没有找到中文版,反正自己最近也在深入学习mongodb,所以正好拿来翻译...首先声明自己的英文水平不是太高,加之有些英文翻译成中文也找不到...
  • 本系列文章翻译自《50 Tips and Tricks for MongoDB Developers》,暂时没有找到中文版,反正自己最近也在深入学习mongodb,所以正好拿来翻译...首先声明自己的英文水平不是太高,加之有些英文翻译成中文也找不到...
  • 本系列文章翻译自《50 Tips and Tricks for MongoDB Developers》,暂时没有找到中文版,反正自己最近也在深入学习mongodb,所以正好拿来翻译...首先声明自己的英文水平不是太高,加之有些英文翻译成中文也找不到...
  • 本系列文章翻译自《50 Tips and Tricks for MongoDB Developers》,暂时没有找到中文版,反正自己最近也在深入学习mongodb,所以正好拿来翻译...首先声明自己的英文水平不是太高,加之有些英文翻译成中文也找不到...
  • 本系列文章翻译自《50 Tips and Tricks for MongoDB Developers》,暂时没有找到中文版,反正自己最近也在深入学习mongodb,所以正好拿来翻译...首先声明自己的英文水平不是太高,加之有些英文翻译成中文也找不到...
  • 本系列文章翻译自《50 Tips and Tricks for MongoDB Developers》,暂时没有找到中文版,反正自己最近也在深入学习mongodb,所以正好拿来翻译...首先声明自己的英文水平不是太高,加之有些英文翻译成中文也找不到合...

空空如也

空空如也

1 2 3 4
收藏数 78
精华内容 31
关键字:

tips翻译成中文