人们为什么仍然说Java很慢?[关闭]


61

在SO和其他地方,Java长期以来一直以缓慢而著称。从笑话问题和答案的许多评论,人们仍然认为Java仅仅基于90年代的经验就很慢。

这是我的问题:我们(大多数)不赞成人们认为Java速度慢的原因。除了小事之外,Java相当快。

那么为什么人们仍然拒绝相信Java很快呢?他们的心态一部分就是没有C / C ++的事情进展缓慢吗?是因为人们不随时间检查吗?是因为人们只是有偏见?


10
嗯,C#也很快;)
Evan Plaice 2010年

12
嗯,那个链接并不能证明Java很慢。

13
我的感觉是Java没有反应,而不是缓慢。
zneak

23
膨胀和可怕的UI库..?
dmp 2010年

4
因为JVM不是内核的一部分。哦,也许有些linux家伙会在将来添加它。
谢耶利

Answers:


131

这是应用程序。当你注意,我们已经证明,一次又一次,在人为的情况下Java代码能够满足,甚至的,如C,C ++,Lisp语言,VB6,或JavaScript的所谓“高性能”语言的表现。当得到这样的证据时,大多数理智,豁达的反对者都会羞愧地垂头丧气,并保证不再散布这种诽谤。

...但是随后,他们启动了Eclipse,NetBeans或Guiffy,或在浏览器中启用了Java支持,或尝试在自己喜欢的功能手机上运行应用程序。他们等待它变得响应...

...然后等待...

...然后等待...



...然后...







...等待...











... ...




...我保证不再做任何事情?抱歉,一定打do睡了...


44
即使是最简单的Java GUI,也至少需要1.5秒才能启动。这不是一点点。
彼得·布顿

32
我从没想过Javascript被认为是“高性能”语言。
zneak

11
+1表示IDE。Eclipse和像Visual Studio这样的IDE的响应能力之间存在巨大差异。
mellowsoon

56
我对此有疑问。Firefox主要是用C ++编写的,它运行缓慢。这是否意味着C ++运行缓慢?不,这意味着Firefox运行缓慢。说一种语言很慢是因为用它编写的最大的程序很慢。
TheLQ

13
乔纳斯(Jonas),使用我能找到的最简单的例子,并不能使我成为一个糟糕的程序员。如果您有一个神奇的方法可以在不到一秒钟的时间内运行Java GUI,请继续进行演示
彼得·布顿

48

这个问题是在错误的前提下进行的:重要的是,Java仍然很慢。重要的是大型数据集上的大量计算算法。当然,可以对它们进行优化,有时可以与C / C ++代码相提并论,但仅以模块化和通用性为代价。可以将高效的C ++代码设计为通用的,并可用作通用库。Java代码不能。试想一下,在高度优化的Array.sort方法,即用不同的实现所有基本类型,且其对象变种仍低于C ++通用较慢sort,因为这些对象必须动态地调度相等比较。

当然,由HotSpot引擎执行的及时优化实际上可以预测这些虚拟调用的目标并尝试内联。但这仍然比在C ++ sort方法中调度的直接内联调用慢。

我的一位前同事已经使用模板C ++实现和面向对象的Java实现对大型数据集(使用动态形状进行q- gram计数)上的问题进行了比较基准测试。Java代码比C ++代码慢几个数量级。

当然,这是将苹果与橙子进行比较。但是关键是,Java实现是最好的实现(就性能而言,考虑到库所需的模块化程度),C ++实现也是。

不幸的是,基准数据不是免费提供的,但是其他人在比较运行时抽象的开销时发现了相似的数字。例如,Scott Meyers在Effective STL中编写了有关C泛型qsort函数的开销的信息:

当涉及到速度时,C ++的排序实际上总是使C的qsort感到尴尬。[…]在运行时,sort对其比较函数进行内联调用…,而qsort通过指针调用其比较函数。[…]在对一百万个翻倍向量的测试中,[sort]的运行速度提高了670%…


6
公平地说,std::sort这是很难用其他语言进行类似操作的情况之一。但是我见过的绝大多数项目都不是在编写std::sort类似代码的代码。他们正在用C ++编写(错误的)Java代码,并抱怨它们有问题。
Billy ONeal

2
您是否有任何报告来备份您的故事,说明大型数据集运行缓慢?我听说有人谈论要进行1-2百万个条目列表的操作,而且这个过程仍然很快。难道不是搞乱了内存中的海量数据集(通常是数据库中的东西)是一个利基领域吗?
TheLQ

8
@TheLQ:来源是Gogol-Döring&Reinert撰写的SeqAn书。关于您的反例:什么操作?他们认为“快速”是什么?同样,1E6条目并不那么大。;-)关于这是否是利基领域–当然。但这是您需要快速计算的地方。关键是Java是否快速,而不是对于廉价操作是否“足够快”。在足够小的数据集上,一切都足够快。
康拉德·鲁道夫

2
没有最好的实现方法
jeremy-george

3
@fonzo可以有一个合理的近似值。抓紧一点,对于足够简单的算法和明确定义的指标,可能会有最佳的实现。就是这种情况。该算法很简单,并且有一个明确定义的案例已进行了优化:给定输入的运行时间。
康拉德·鲁道夫

28

因为它很慢...在某些应用程序中。桌面应用程序必须从一开始就做出响应,并且启动开销很慢。

另一方面,如果您运行服务器,则是否发热(JIT分析和编译)并不重要-您只需在蓝月亮中进行一次,因此在大多数情况下都不能认为它完全慢。


启动成本是一个问题,但是您可以使用一些命令行开关进行调整
TheLQ 2010年

22
实际有多少用户了解命令行开关?
Walter 2010年

17
TheLQ,如果你能提供一个命令行开关删除为Swing / AWT的1.5秒启动延迟,请继续前进,回答这个问题:stackoverflow.com/questions/508723/...
彼得·鲍

6
如果单击包含Java事物的链接,如何调整这些命令行开关以避免整个浏览器锁定5秒钟?那种事情使人们对Java的调用变慢了,并且一旦加载它实际上运行得很快就没关系。
Roman Starkov 2011年

21

我说这是因为当人们第一次遇到它时,它很慢。基于此,他们对它产生了印象。如果他们不使用它,则该印象不太可能改变,并且由于该印象,他们不使用它-这是一个恶性循环。

我必须承认,我给人的印象是Java的运行速度很慢,是的,那是由于我以前接触过它。从那以后,我现在开始使用不同的语言,并且接触Java的机会非常有限。因此,我的看法并没有太大改变。


3
+1-我完全同意。我讨厌Java的早期。.NET Framework确实帮助了托管代码的实现:我喜欢C#,最终我也喜欢Java。
Wizard79 2010年

7
运行Hello World仍然需要一秒钟的时间。启动时间很慢。
直觉

@intuited尝试通过C ++ / C#或任何您能找到的HECK语言来构建服务器,尝试使用C进行构建,然后与JAVA进行比较。C的作用是,如果您是“ Ma,我编写了10行C代码,比Java快,但您看不懂它”,那家伙会很快。当您的C代码增长时,您的速度会变慢;)
AceofSpades 2012年

16

因为需要一代人的时间才能改变人们对产品的看法

它与Java的发展速度无关。在人们看来,Java是与单词“ slow”相关联的const标识符。您或Oracle几乎无能为力。

高兴的是,Oracle还没有通过轻率或愚蠢的事情破坏Java编程文化。就像收取过多的使用许可费用。或基于Sun先前拥有的软件专利起诉人们。::叹::

我不想在这里成为反对者,但是,除非甲骨文和谷歌以友好的方式解决Java争端,否则谷歌被迫购买Java并使其成为“合适的”开源平台,否则Java一定会成为孩子有虱子的操场。IE,没有人会想用20英尺高的杆子来触摸它。

注意:请明确地说,当我说一代时,我是在用人的术语而不是计算机的术语说话。IE,直到持有该感知的人过世或被年轻一代取代,该感知才成立。用5年而不是5年来思考。


2
我认为Google使用了太多Java,以至于他们购买Java并不是完全不可行的理论。我可能会对此感到满意。
Bart van Heukelom

1
@donroby:谁在乎这些语言?Java将在二十年内成为一种利基语言。
2010年

1
@aasc-Java可能在二十年后就过时了,但是LISP现在不是,也不会在那时。
唐·罗比

2
@aasc“编程语言通常不会存在超过一代人”好人,一百万个Pascal的Delphi开发人员,五百万个Visual Basic开发人员出错了……更不用说Perl,Lisp,Fortran,Cobol,C ++了吗该评论的任何理由???
真正符合道德的2010年

2
@Reallyethical不是主流。有多少企业依赖Lisp,Fortran和Cobol。使用Lisp时,它大多陷于学术界,并被用作其他语言功能的模型,很少有人将其用于实际的生产项目。Fortran已成为高性能数学建模的利基语言,而Cobol仍然存在,只是因为银行业非常害怕将其旧的/可靠的代码更改为新平台。C ++是一个明显的例外,因为它今天仍然非常广泛地被使用和采用。
Evan Plaice 2010年

11

原因之一是人们信任别人怎么说,而不是别人看到的东西

根据我刚开始编程时所得到的信息,Java比C ++“慢”,之所以可以使用Java,是因为它“方便且容易”。人们通常认为Java以性能为代价带来安全性和便利性。即使后来发明了C#,人们仍然认为它比Java更快,因为它是“本机”的。

但是人们不知不觉中发现的事实是,eclipse是用Java构建的IDE,绝对是同类中最快的IDE。我使用了几乎所有主流的IDE,包括来自MS和GNU,Borland的主流IDE,eclipse是IDE的绝对王者,主要是因为它的速度很快。

另一个原因是启动时间长

Java不适合开发留在系统托盘中的微型应用程序,会占用少量内存,并弹出一个对话框提醒您休息;或用于打开文本文件,阅读并关闭它的记事本。它应该在BIG之类的东西上使用,例如始终存在的Web服务器,以优化利用计算资源,每小时响应数百万个请求。或者像eclipse这样的IDE可以管理数千个工作区文件。我相信,直到Java应用运行至少几个小时,您才知道它的运行速度。


1
我一直都很迟钝。
aasc

28
Eclipse快吗?LMAO
finnw 2010年

2
@finnw-如果您对其进行调整。开箱即用,并带有所有插件,显然它不会很快。显然,它永远无法与vim或jedit或Notepad ++相提并论,但是这些“快速”或“缓慢”的参数和语句在没有上下文的情况下是毫无意义的。
luis.espinal,2010年

2
但是,您可以将@luis与Delphi 7进行比较,我不认为它比Eclipse更简单。而Delphi 7几乎与记事本一样快。太疯狂了
Roman Starkov 2011年

4
@finnw,对于拥有成千上万个插件的IDE来说,它是非常快的:)

8

@bigown“为什么人们仍然说Java很慢?”

因为他们很笨。因为他们没有工作经验,但是认为他们是Dikjstra的活着化身,还是Linus Torvald的第二次来世,哦,我不知道。说出这种智障的原因的原因很多,但通常是愚蠢,无意识的主观狂热和情感上的关注-背后的原因。

让我们对此进行剖析,以便您可以了解我上面所说的事实:

首先,在什么情况下,在什么情况下,在什么情况下,在什么条件下,在什么工程/科学/商业目的下慢(说它很烂不是其中之一)。任何对任何技术说“ X慢”的人X,或简称为“ X is Y”,其中Y是某种否定性陈述,如果不回答上述任何问题,则视为傻瓜。诸如此类的声明在工程中没有位置。可能在政治和青少年聊天室中,但在工程学中则没有。

其次,大多数这些被误导的傻瓜都对Java的运行速度感到哭泣,因为ZOMG使其日食永远耗费时间(哎呀,用所有插件加载东西,然后猜测会发生什么。)这些傻瓜中的大多数甚至都不知道如何调整jvm以使Eclipse能够快速运行(或针对任何Java应用程序)。也就是说,他们对性能调优一无所知,这不仅对于Java,对于任何非平凡的系统(无论是硬件还是软件)都是现实。因此,在这种情况下,他们在做出这种无意识的声明时出于任何技术上的有效性而无法武装自己。

第三,让我们考虑一下Java开发的主要目的:首先是后端OLTP;然后是OLTP。监控系统排名第二。两种类型的系统都旨在在集群中运行,并且连续运行数周甚至数月。那么,当REAL Java应用程序的目的是长时间运行时,您的小日食或玩具应用程序需要花费一两分钟的加载时间真的重要吗?上下文,人员,上下文。

最后,Google和Ebay上OLTP的主干运行在Java上。我将其作为矛盾的证据来证明Java并不慢(至少在重要的条件下,不是为了小小的玩具实验,基准测试和无法验证的附带证据而专门为说“ tehe X慢,很烂”而做)。

有工程,有狂热。猜猜那些属于哪些类别声明?


19
如果我必须调整JVM以使Java能够以可接受的速度快速运行,而我不必调整任何东西(除外-O2)以使C ++可以以可接受的速度快速运行,则Java速度很慢。
David Thornley,2010年

@David-明显的声明。谁都知道Java比C ++慢。但是,从逻辑上讲,这并不慢。提及gcc标志均未给出注释的有效性。它只说it is slower than something else.美洲虎比猎豹慢。这使前者成为现实slow吗?尝试一些工程的客观性和问问你自己:可以在一个逻辑声明,arbitrarily即什么是slow简单,因为it is slower比别的东西without mentioning a context of operations,它定义了是fast enough为了什么?逻辑上可以吗?
luis.espinal,2010年

5
@ luis.espinal:我对您的理由2的回答是:人们说Java的速度很慢,因为您认为他们没有调优Java。还请注意我对“可接受的快速”的使用。在我看来,某些“不可接受的快”的东西是缓慢的,在我看来,人们通常声称是慢的某件事可能不是可以接受的快。
David Thornley,2010年

4
@luis espinal您听起来像是Kant :)这里的人做了一个隐含的假设,即慢速意味着比其他实用的,可立即投入生产的语言(如C ++)慢。(记住物理学?)当您测量势能时,您始终会相对于某些地面进行测量。现在按照您的语法,“ X是愚蠢的”是毫无根据的。“ X比Knuth愚蠢”并不能使X成为绝对的哑巴,因为几乎所有人都可以成为X。我同意称语言缓慢不是精英,但是这里的人说的不是“哑巴”,而是碰巧做出了一个隐含的假设。
yati sagade

1
@luis haha​​a ..不错的观察。(我相信您是Kant的转世,变得更加扎实;))这样的讨论最终以火焰大战和无效的击键而告终……据我称,人们应该始终坚持看似最好的工具来应对手头的工作。同意,Kant2吗?:P
yati sagade 2011年

8

因为是这样,我们可以永远结束这个话题吗?

https://days2011.scala-lang.org/sites/days2011/files/ws3-1-Hundt.pdf [向下滚动至表格,Java比C ++慢3.7-12.6倍,谷歌员工研究]

PS:如果不是这样,请至少给我命名一个快速的Java应用程序,之前从未见过。


6
请在您的答案中总结PDF的内容。
亚当·李尔

1
本文与科学研究标准相去甚远。它甚至没有比较所有语言中完全相同的算法和优化。“ E. Java Tunings Jeremy Manson将Java的性能与原始C ++版本相提并论。该版本保存在java_pro目录中。请注意,Jeremy故意拒绝进一步优化代码,许多C ++优化将适用于Java版本。” jeremymanson.blogspot.com/2011/06/scala-java-shootout.html
Piotr Kolaczkowski

6

TMHO,这是因为在浏览器中启动VM所需的时间。如果应用程序启动缓慢,人们只会记住这一点。因为,长时间的启动确实很烦人。真。我的一位同事告诉我,他不使用Firefox,因为它太慢了。(?!?)。但是,是的,好的,在Windows上,Firefox需要花费大量时间才能显示出来。据他介绍,这个应用程序运行缓慢,他决定要注意它的总体速度。


这就是Mozilla花费大量精力使Firefox快速启动的原因...
Spudd86

2
可能看起来像Windows。是的,登录后您很快就会看到桌面,但是您仍然需要等待一段时间才能使其响应。
Bart van Heukelom

6

比起慢什么?我正在考虑从普通的Ruby更改为JRuby(基于Java的ruby),因为我听说它更快。


1
即使在1.9中,JRuby 比Ruby更快。但是,差距正在缩小。
Dan Rosenstark 2010年

2
+1指出一个大问题。尽管我会说OP可能与C#或C ++相提并论。
Billy ONeal 2010年

@Yar,您指出CRuby正在赶上JRUby?

6

意见是意见,事实是事实。

这是Google Code Jam的一个事实,它可以挑战程序员在短时间内解决棘手的计算问题,这意味着他们使用的语言的性能起着重要的作用:

在过去的版本(2009年,2010年和2011年)中,进入决赛的程序员中约有75%使用C ++,而使用Java的则约为15%。

来源-> http://www.go-hero.net/jam/


3
但这仅能真正证明Java 可以使其在以速度为中心的竞争中脱颖而出,但是大多数人选择C ++。
亚当李尔

3
“在短时间内解决棘手的计算问题” –什么,编写代码所需的时间,或运行代码所需的时间?无论如何,您的事实是-一个事实-与问题有什么关系?您是从事实中得出结论吗?
occulus 2012年

这可能只是因为有75%的人编写了最后一轮程序后,认为Java尚未测试就很慢,因此改用C ++,因为他们认为Java从未测试就很快。
jwenting

4

大约在1997年,我使用了HP Vectra VE(200 MHz)和Windows95。大多数应用程序在此上运行非常快,但是后来我尝试了一些用Java编写的应用程序(如果我没记错的话,是IDE)。它们非常慢,至少是其中的GUI部分。他们花了很长时间才能启动,并且GUI元素(例如菜单)的响应速度不是很好-视觉反馈存在延迟。另外,由于Java GUI应用程序具有(非常)独特的外观,因此我学会了将此外观(和Java)与较差的性能相关联。


2
我记得1997年!伟大的一年,尽管1997年以来的许多葡萄酒-和观察-不再可用。
Dan Rosenstark 2010年

1
我也记得1997年。Windows一直崩溃,并且在安装驱动程序时需要重新启动。一块垃圾。

而且您没有改变对1997年的看法吗?您是否注意到2011年与1997年完全不同?
杰斯珀,

5
我从这些数据中得出的分析是1997年很糟糕。
JasonTrue 2011年

4

这取决于您所说的缓慢。

首先,java最近取得了许多进步,并且在大多数情况下非常快。但是:

  • Java启动缓慢,因为您必须在执行任何操作之前先加载JVM。
  • 在某些情况下,某些安全功能可能会降低性能。随机访问的边界检查就是一个例子。
  • 在Java中使事情变得非常快需要与JVM配合使用(以利用缓存行为例)。
  • 缺少元编程意味着每种抽象在运行时都会受到惩罚,因此,在许多情况下,性能会影响设计成本。
  • Java很难通过设计确保实时性,某些人认为这是“缓慢的”。

顺便说一下,在某些情况下,java比普通的C / C ++更快。但是那些语言为您提供了调整它们的工具。

Java是一种针对生产力的编程语言。现在,它对于大多数应用程序来说已经足够快了,但是对于其他一些应用程序来说还不够。

通常,Java的速度过慢是一个过度使用的论点,因为在大多数情况下它是毫无意义的。


2

简单,规范的Java代码往往与简单,规范的C / C ++ / D代码同等或更快。简单,规范的代码往往会不必要地执行大量内存分配,没有特别针对任何CPU架构进行调优,没有对它进行大量的低级优化,等等。Java的HotSpot GC令人惊叹,VM优化比静态编译器可以做的更好。

另一方面,如果您确实需要性能,并且愿意手动调整性能以获取性能,则C / C ++ / D为此提供了更多机会。您不能在Java中使用内联汇编程序。您不能使用脏类型的校正技巧将浮点数视为位数组。对于您的特定用例,您不能使用可能比GC更快的自定义内存管理方案。在Java中,您不能在堆栈上分配比在C / C ++ / D中那么多的内存。在Java中,获得与高阶函数大致相当的任何东西的唯一方法是使用接口和运行时绑定。在D和C ++中(如果我错了,请纠正我),您可以将函数传递给模板,从而允许在编译时进行绑定而不会失去灵活性。


5
您可以提供这些评论吗?也就是说,在哪里有基准能显示每种语言的规范代码,从而显示Java更快?
Billy ONeal

1

Java“慢”的另一点是64位运行时。

我听说有人抱怨Java在64位计算机上对他们而言非常慢。事实证明,64位Java运行时使用服务器JVM,该服务器在启动之前会编译整个程序。

这里是解释为什么64位VM启动速度较慢的原因。

例如在Windows上:

C:\> java -version  
java version "1.6.0_21"  
Java(TM) SE Runtime Environment (build 1.6.0_21-b06)  
Java HotSpot(TM) 64-Bit Server VM (build 17.0-b16, mixed mode)  

3
服务器虚拟机是慢启动,但它并没有原生开始之前编译整个程序。不能,类被延迟加载并可能通过反射加载,因此无法预先知道需要本机编译哪些字节码。
Dan Dyer 2010年

@Dan Dyer经过一番研究,看起来我误解了我所读的内容。我的意思是Server VM进行了更多优化,而Client进行了优化以实现快速启动和较小的内存使用。
AndrejaKo 2010年

服务器VM已针对长时间运行的进程进行了优化,因此预加载了更多虚拟机,这导致更长的启动时间并倾向于使用更多的RAM。客户端VM已针对减少占用空间和启动时间进行了优化,但可能会降低运行时性能。
jwenting

0

Java的性能是非常主观的,但是,为什么Java这么慢的理解很大程度上是由于其他人已经指出的原因:大多数人对某种事物的理解是由他们早期的使用经验所染上的,而Java并非一直是一种经过良好优化的语言。引擎盖。同样,与像Visual Studio这样的IDE相比,香草Eclipse也不是一种可以快速使用的IDE,并且在响应能力方面显得苍白。

也就是说,除了Java在启动时遇到的UI问题之外,它对于大多数应用程序来说足够快。如果您进行搜索,则会发现将其与其他语言进行比较的文章,并且所显示的大多数结果都将其归类为仅在处理主要数据集时才有问题的范围。

在生物信息学领域,它得到了广泛的使用,因为它得到了很好的支持,并且已经为它提供了安装基础。Java的优点之一是,您可以使用它进行一些相当快速的开发,而这是C语言无法完成的。如果您查看用于生物信息学的语言(我个人经常使用R,Python和Java),您会注意到它们都不是最快的,并且生物信息学中的数据集运行到100年代并不罕见。千兆字节的信息。归根结底,人工时间仍然更具价值,虽然速度差异明显,但数据集的大小往往足够大,以至于它们无论如何都要通宵运行。

如果使用Java编写简洁的UI更加容易,那么速度感知将像雷达一样逐渐消失,因为大多数人没有足够的语言来推动速度,这确实是每天的问题。


0

抛开一文不值的钱,我发现Java Web应用程序通常具有很长的启动和响应时间,在我看来,Python或Ruby会做得更好。

我在大多数编程中都使用Eclipse,并且必须说Java与其他任何事物一样快,即使在本地和“独立”环境下运行得更快。


1
在网络上,启动时间并不那么重要。最重要的是资源消耗和可伸缩性。
Berin Loritsch 2010年

-7

我会说Java无限慢,而不仅仅是速度慢,因为Java无法解决在真正的高级语言中容易解决的简单问题。

让我举一个简单的例子。有两次映射列表时适用的简单优化,称为砍伐森林:这是用我的语言Felix编写的规则:

reduce deforest[T,U,V] (f:T->U, g:U->V, x:list[T]): 
  map g (map f x) => map (compose(g,f)) x
;

这表示:不是将列表x与f映射,而是与g再次映射,需要两次遍历列表并创建一个垃圾临时列表,只需将列表与函数组成进行映射即可。

这是一个高级优化,远比Java JVM的低级性能重要得多。我上面给出的规范不仅是漂亮的语法,这是 用户编写的一条指令,告诉Felix编译器如何执行优化。

请告诉我如何在Java中执行这种操作。没有?然后Java很慢。非常慢。[我相信Haskell可以自动执行此操作]。

在您说“但是Java是一种OO语言之前,这种优化并不适用” ..那正是我的意思。Java很烂,而成为OO是主要原因。

JIT优化永远无法与像样的编译器可以完成的优化竞争。


3
我完全不知道您的代码在那里做什么。而且,如果您说整个语言之所以缓慢是因为它无法进行一次小的优化,那么这里还有其他问题
TheLQ 2011年

7
-1挖掘一个旧问题,并以非常arguments脚的论点抨击一种语言。告诉我,如果您想详细撰写推理方面的问题。对于初学者来说,将OO命名为糟糕的主要原因并不是很客观,即使有优化,JVM + JIT的实际性能也非常好。

8
对于我们的主要平台,Haskell绝对比Java慢,因为它没有移植到上述平台,因此Haskell很烂……

1
@ThorbjørnRavn Andersen我真的希望我能为您提供+1。
Patrick Hughes
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.