zoukankan      html  css  js  c++  java
  • java、c/c++ 、python 等性能比较 杂谈(整理)

      

    链接:https://www.zhihu.com/question/40393531/answer/133242263
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    有人用python写的代码如下:
    #-*-coding:utf-8-*-
    import time
    def isPrime(i):
        for test in xrange(2,i):
            if i % test == 0:
                return False
        return True
    
    if __name__ == '__main__':
        t1 = time.clock()
    
        n_loops = 50000
        n_primes = 0
    
        for i in xrange(0,n_loops):
            if isPrime(i):
                n_primes += 1
    
        t2 = time.clock()
        print str(n_primes)
        print "run time:%f s" % (t2 -t1)
    
    基于numba加速代码
    #-*-coding:utf-8-*-
    import time
    from numba import jit
    
    @jit
    def isPrime(i):
        for test in xrange(2,i):
            if i % test == 0:
                return False
        return True
    @jit
    def tp():
    
        n_loops = 50000
        n_primes = 0
    
        for i in xrange(0,n_loops):
            if isPrime(i):
                n_primes += 1
        return n_primes
    
    if __name__ == '__main__':
        t1 = time.clock()
        n_primes = tp()
        t2 = time.clock()
    
        print str(n_primes)
    
        print "run time:%f s" % (t2 -t1)
    
    (这里插入一些知识:解释器与编译器 ,和 Python解释器)
     

    我用python执行时间23秒,用pypy执行时间1.54秒,用numba加速为1.5秒,c语言在本机macos上执行时间1.3秒,java运行速度1.45秒(jre8),详细见图片,可见引入jit编译后,性能直逼c语言,而写python比写c容易太多,比java简洁,写代码速度也是非常非常重要。由于历史原因,很多python库用的c语言库,如pandas(pandas的矩阵计算用numpy优化过非常快,可能比手写c语言循环还要快),可以通过设计来分离c语言加速后的python代码和pure python,分别用不同的加速方法,如numba可以单独加速一个函数,把需要大量计算的放在一个函数用numba加速(numbapro支持显卡加速但是商业版的)。

    所以只适当设计一下,python在一般计算问题下有这些解决方案下性能不是问题,实在不行,你还可以用boost::python来写个c/c++调用库来解决性能问题。

    下面的测试说明,对于性能,原生python比较慢,在windows下python比linux,macos要快,用pypy后相当于java,c#速度,pypy,c#在windows下受益msvc表现较快,,go语言速度表现比较稳定,c语言理论上是最快,但受环境和编译器影响较大。对c#,java可能在GC垃圾回收时会表现不稳定,因为在oop中有大量计算后可能要回收垃圾内存对象,这个没有用到oop,只是纯计算,理论上还是c/c++语言最快。

    python和java比,运行速度比java慢,java强大于改进n次的强大jre,但python在很多领域能调用很多现成的开源库,在数据分析中有优势,pyhton的代码比java要简洁,容易入门和使用。在优化的计算库帮助下,如numpy numba,pandas,scikit-learn,python的实际问题运算性能并不低于java。java主要是框架太多,相对复杂,java主要用于业务程序开发,符合软件工程理论,可伸缩性强,强类型有利于对程序的静态检查分析。java随着安卓,hadoop,spark的兴起,加入java语言的公司很多,性能也可以通过优化解决很多问题。很多服务器如ubuntu server,centos都默认支持python,而java虚拟机需要安装配置,python的安装使用也相对简单。python的库有开箱即用感,很多业务领域,你可能还在用oop写代码,考虑设计模式,用锄头挖沟时,而python调用挖掘机api已经炒菜完工开饭了,缺点是油耗比较大。

    Python和c#相比,c#依赖强大的微软优化的.net虚拟机和强大vs ide,在windows平台下运行速度比java要快,但跨平台运行后如mono,速度就慢了,功能也不完全。c#的跨平台能力比不上python,c#比python要复杂,c#语法和java,c++借签,比较受编程人员喜好。mono的出现,unity3d用c#调用c++做游戏业务逻辑,可以在手机上流畅运行,体现了很多程序的性能在于良好的设计,可以把高性能的用c/c++写,用c#,java,python写容易变化的业务逻辑部分。c#在mon虚拟机下运行速度还可以,但linux控在服务器上有java,python,php,所以用mono做web比较小,从unity3d的成功来看,用c#做为业务脚本语言,用c++做库也能获取很高的性能。这是折中性能和开发速度矛盾的一种解决方案。很多复杂的业务语言用java,c#,在团队开发时易用性好,也说明了python的工程化比较差,对强类型的支持弱不适合静态分析,但python一但用强类型申明,那么是另一种java,也就不是快捷语言。在单纯的计算比较,各个虚拟机语言相差不多,其实除了现代很多业务系统瓶颈在io,在网络,在算法,在设计,你2秒运行1.2亿次,而没有数据库或缓存能做到2秒内记录完1.2亿条数据,都是1秒在1百万记录以下,如果走网络速度更慢,持续平均1秒能记录下几十万条数据顶天了,所以这些语言一直在等io完成任务。

    python和go语言相比,go语言相对较新,go语言的库没有python的丰富,毕竟python发展了几十年,go语言最大的优点是协程,速度快,支持高并发,但任何支撑高并发的语言编程都不是一件易事,最大的缺点是,名称有google的go,所有很多其他的巨头公司本着竞争的观念对有类似商标的语言有抵制心理。而python是开源,用得公司特别多。go语言的语法如果能像c#,java类似,可能会发展得更好。很多语言为什么会用它,不在于语法,不在于性能,主要在于这个语言开发了什么成功的产品,另人会mock这个产品,用这个语言,Docker就是go语言开发的,适就于大规模分发容器。

    python语言和c/c++相比,python开发速度比c/c++快,因为c/c++有指针,干什么之前,需要考虑好指针的技巧,指针弄不好,会造成内存泄露,一点内存泄露不要紧,但乘以时间乘数就会耗尽整个内存,因内存泄露造成的24h*365天服务器需要重启会造成实际经济损失,所以开发商业后台业务程序最好用无指针的java,php,python。但对用户来说python,java,c#,c/c++开发同样功能的程序,用户会选择c/c++,所以在软件业无数成功的标牌软件是c/c++,这是c/c++的成熟之处。c/c++主要是开发成本高,同样的程序可能python,c#一周,c++搞二个月很正常。但为了利益,花再多时间也有人干,如同现在一样有人用汇编写加密代码,用FPGA把程序做成芯片,追求的是极致的速度。c/c++的快是直接编译成二进制,无jit,vm,而python最快也只是调用c的扩展。开发成本也是很高的成本,高级的c++程序很贵,如在美国高级的c++程序员年薪在百万人民币以上,有时不是大应用时,用易于使用的语言,上高级点的电脑,上集群就可以了。如用python显卡来加速,买个显卡也就万元。c/c++适合精雕细琢,走精英路线,python适合快速开发,走大众路线,其实对于影响性能的部分可以结合使用,用python调用c/c++库。随着编译技术进步,电脑的计算力成本会随时间下降,计算力越来越强,最近的cpu多核主频高达5g,理论上比2.5g的cpu算力快一倍,用液氮超频可达6.7g,同样的核也比我电脑快了1.5倍(如果用高级c++语言程序员优化了1倍时间花费1人/年,显然超过了换计算机的钱),显卡在多核的支持下浮点运算能力也越来越高(可用NumbaPro,PyCUDA), HPC在云市场可以租用到,超级计算机也可以向有关组织租用机时测试,动态语言以其易用性开发成本低在很多领域可以取代高性能的编译语言,但极致的编译性能软件市场也是不断扩大的,很多行业算力跟不上,很多np-hard问题对算力需求不是线性增加能满足的,人们对性能的需要实际是越来越高,如世界竞争的超级计算机,比特币矿机,深度学习算法。谁都不可以取代谁,而是大家都结合发展了。用什么语言没有好坏之分,关键是在目标程序追求的是什么。

    链接:https://www.zhihu.com/question/40393531/answer/133242263
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

    实际上我心中觉得最好的x语言是
    java的跨平台+c#的ide和语法+python的库+c++语言的性能+go语言的协程

    python在macos执行时间23.3秒,pypy在macos执行时间1.54秒,python在ubuntu下测试为13.5秒,pypy在ubuntu下测试为2.3秒。

    用numba加速在macos结果为1.5秒。
    python在windows7下运行时间为7.4秒,pypy在windows7下的运行时间为0.6秒。

    用不同python编译器在win7下运行的结果,pypy为0.56秒,jython为4.7秒,IronPython为5.2秒,python为6.5秒

    c语言在macos运行结果1.34秒(LLVM)
    c语言(vc++13)在windows7下的运行时间为0.34秒,为什么会这么快,可能和msvc的编译器对windows平台数字计算优化有关。包括上面的windows下的python,用msv编译版后速度较macos要快。c语言我在ubuntu下用打-O2优化,用gcc是2秒,用clang是1.88秒。
    c语言打开-O2二级优化,用llvm和gcc,速度差不多都在1.2秒,clang要快点

    java在macos运行结果1.4秒,我在ubuntu上测试为2秒。

    java在windows7下的执行时间为1.23秒
    go语言测试代码如下:
    package main
    import (
    	"fmt"
    	"time"
    )
    func main() {
        n_loops := 50000
        n_primes := 0
        t1 := time.Now() // get current time
        for i := 0;i < n_loops;i++ {
    	    if  isPrime(i) {
    		    n_primes++
    		}
    	}
        t2 := time.Since(t1)
        fmt.Println("Time taken=", t2)
        fmt.Println("primes found",n_primes);
    }
     func isPrime(i int)(bool){
        for test := 2; test < i; test++{
            if  i % test == 0 {
                return false
            }
        }
        return true
    }
    
    go语言在macos测试结果1.1秒,我在ubuntu下测试为0.91秒

    go语言在windows 7平台下1.18秒,你还可以用Grumpy,把python先转换成go语言,再编译go语言成二进制实现加速。

    c#基于mono在macos执行时间2.84秒,在ubuntu上测试为1.8秒。

    c#基于windows7执行时间1.17秒

    c#代码如下:
    using System;
    
    namespace TestPrime
    {
    	class MainClass
    	{
    		private static long LoopCount=0L;
    
    		private static bool isPrime(long i)
    		{
    			for (long test = 2; test < i; test++)
    			{
    				if (i % test == 0)
    				{
    					return false;
    				}
    				LoopCount++;
    
    			}
    			return true;
    
    		}
    
    		public static void Main(string[] args)
    		{
    			TimeSpan start_time = DateTime.Now.TimeOfDay;
    			long n_loops = 50000;
    			long n_primes = 0;
    
    			for (long i = 0; i < n_loops; i++)
    			{
    				if (isPrime(i))
    
    				{
    					n_primes++;
    				}
    			}
    
    			TimeSpan end_time = DateTime.Now.TimeOfDay - start_time;
    			Console.WriteLine(n_primes + " primes found");
    			Console.WriteLine("Time taken = " + end_time.TotalSeconds);
    			Console.WriteLine("LoopCount = " + LoopCount);
    
    
    		}
    
    	}
    }
  • 相关阅读:
    idea安装
    IntelliJ IDEA 简单使用
    git客户端安装
    一、AJAX
    一、JSP标签介绍,自定义标签
    注解
    线程
    网络编程Socket
    一 批量插入数据(使用批处理
    day87
  • 原文地址:https://www.cnblogs.com/nucdy/p/6703780.html
Copyright © 2011-2022 走看看