python官网的下载速度超慢(如何解决python官网下载很慢)

http://www.itjxue.com  2023-04-13 10:31  来源:未知  点击次数: 

python运行速度慢怎么办

yxhtest7772017-07-18

关注

?分享

??697??????2

python运行速度慢怎么办?6个Python性能优化技巧

?

Python是一门非常酷的语言,因为很少的Python代码可以在短时间内做很多事情,并且,Python很容易就能支持多任务卜谈和多重处理。

Python的批评者声称Python性能低效、执行缓慢,但实际上并非如型凳碰此:尝试以下6个小技巧,可以加快Python应用程序。

关键代码可以依赖于扩展包

Python使许多编程任务变得简单,但是对于很关键的任务并不总是提供最好的性能。使用C、C++或者机器语言扩展包来执行关键任务能极大改善性能。这些包是依赖于平台的,也就是说,你必须使用特定的、与你使用的平台相关的包。简而言之,该解决方案提供了一些应用程序的可移植性,以换取性能,您可以获得只有通过直接向底层主机编程。

下面这些扩展包你可以考虑添加到你的个人扩展库中:

Cython

PyInlne

PyPy

Pyrex

这些包有不同的作用和执行方式。例如,Pyrex 让Python处理一些内存任务变得简单高效;PyInline可以直接让你在Python应用程序中使用C代码,虽然内联代码被单独编译,但是如果你能高效的利用C代码,它可以在同一个地方处理每一件事情。

使用关键字排序

有很多古老的Python代码在执行时将花费额外的时间去创建一个自定义的排序函数。最好的排序方式是使用关键字和默认的sort()方法。

优化循环

每一种编程语言都强调循环语句的优化,Python也是一样的。尽管你可以依赖于丰富的技术让循环运粗樱行的更快,然而,开发者经常忽略的一个方法是避免在循环内部使用点拼接字符串。

使用新版本

任何一个在线上搜索Python资料的人都会发现无数关于Python版本迁移的信息。通常,Python每一个版本都针对之前的一个版本做了优化和改进,以让Python运行的更快。限制因素是你喜欢的函数库是否也针对Python的新版本做了改进。

当你使用了新的函数库,获得了Python的新版本,你需要保证代码依然能够运行,检查应用,修正差异。然后,如果你仅仅是

python爬虫下载图片速度很慢如何解决,具体点,新手

下载慢这个很难判断啥原因,而且你没把代码贴出来,你又没说爬虫是自己写的还是用衫薯第三方成熟库,很可能你没使或茄者用多线程来下纳腊载操作。

为啥我的Python这么慢

Pythn是动态类型而不是静态类型的,这意味着,在程序执行时,解释器并不知道变量的锋明类型。对C语言来说,编译器在声明变量的时候就知道其类型了;对Python来说,程序执行时只知道一个变量是某种Python对象。

对于银猜告下面的C代码

int a = 1;

int b = 2;

int c = a + b;

编译器始终知道a和b是整型,在执行相加运算时,流程如下:

把int 1赋值给a

把int 2赋值给b

调用binary_addint, int(a, b)

把结果赋值给c

实现同样功能的Python代码如下

a = 1

b = 2

c = a + b

解释器只知道1和2是对象,但是并不知道这个对象的类型。所以解释器必须检查每个变量的PyObject_HEAD才能知道变量类型,然后执行对应的相加操作,最后要创建一个新的Python对象来保存返回值,大致流程如下:

把1赋值给a

设置a-PyObject_HEAD-typecode为整型

设置a-val = 1

把2赋值给b

设置a-PyObject_HEAD-typecode为整型

设置b-val = 2

调用binary_addint, int(a, b)

a-PyObject_HEAD获取类型编码

a是一个整型;值为a-val

b-PyObject_HEAD获取类型编码

b是一个整型,值为b-val

调用binary_addint, int(a-val, b-val)

结果为整型,存在result中

创建对象c

设c-PyObject_HEAD-typecode为整型

设置c-val为result

动态类型意味着任何操作都会涉及更多的步骤。这是Python对数值操作比C语言慢的主要原因

Python是解释型语言

上面介绍了解释型代码和编译型代码的一个区别。智能的编译器可以提前预见并优化重复或不需要的操作,这会带来性能的提升。编译器是一个大的话题,这里不会展开。

Python的对象模型会带来低效的内存访问

和C语言的整数对比时,我们指出了Python多了额外一层信息。现在来看看数组的情况。在Python中我们可以使用标准库中提供的List对象;而在C语言中我们会使用基于缓冲区的数组。

最简单的NumPy数组是围绕C数据构建的Python对象,也就是说它有一兆轮个指向连续数据缓存区的指针。而Python的list具有指向连续的指针缓冲区的指针,这些指针每个都指向一个Python对象,结合上面的例子,这些Python对象是一个整数对象。这个结构像下面这样

很容易看出,如果你正在执行按顺序逐步完成数据的操作,numpy的内存布局比Python的内存布局更为高效,无论是存储成本还是访问的时间成本。

为什么使用Python

鉴于Python天生的低效率,我们为什么还要使用Python呢?种种理由大致可以归结为:动态类型使得Python比C更容易使用。Python非常的灵活和宽容,这种灵活性可以有效地利用开发时间,并且在那些确实需要C和Fortran优化的场合,Python可以轻松链接到已编译的库中。这也是Python在科学社区的使用率不断增长的原因。经提到了一些结论性的东西,下面我们用Python的一些工具来做一些验证。

下面的实验使用到了python, ipython, numpy,版本信息如下:

python:3.6.5

1.13.3

In [1]: import sys

In [2]: import numpy

In [3]: sys.version[:5]

Out[3]: '3.6.5'

In [4]: numpy.__version__

Out[4]: '1.13.3'

本次实验使用机器64位的机器,如果是32位的机器话,下面提到的一些struct可能会有所不同。

整数

Python的整数使用起来非常简单。

In [5]: x = 42

In [6]: print(x)

42

接口的简单性掩盖了底层的复杂。在之前的内容里有提到过Python整数的内存布局。现在我们使用Python内置的ctypes模块来自省整数类型,前提是需要知道在C API中Python整数类型的定义。

在CPython中,变量x存储在一个名为_longobject的struct中,源码见Include/longintrepr.h

struct _longobject {

PyObject_VAR_HEAD

digit ob_digit[1];

}

其中PyObject_VAR_HEAD是一个宏,在Include/object.h中定义的结构如下

typedef struct {

PyObject ob_base;

Py_ssize_t ob_size;

} PyVarObject;

其中PyObject在Include/object.h中定义如下

typedef struct _object {

_PyObject_HEAD_EXTRA

Py_ssize_t ob_refcnt;

struct _typeobject *ob_type;

}

其中_PyObject_HEAD_EXTRA是一个在Python版本中通常不使用的宏。

将上面的信息结合起来,可以得到下面的结构

struct _longobject {

long ob_refcnt;

PyTypeObject *ob_type;

size_t ob_size;

long ob_digit[1];

}

这里面ob_refcnt变量是对象的引用计数,ob_type是指向包含该对象所有类型信息和方法定义的结构的指针,ob_digit保存实际的数值。

有了上面的知识,可以开始使用ctypes模块来观察时间的对象结构并提取上面的信息。

现在来用Python定义一个C的struct

In [7]: import ctypes

In [9]: class IntStruct(ctypes.Structure):

...: _fields_ = [

...: ("ob_refcnt", ctypes.c_long),

...: ("ob_type", ctypes.c_void_p),

...: ("ob_size", ctypes.c_ulong),

...: ("ob_digit", ctypes.c_long)

...: ]

...:

...: def __repr__(self):

...: return (

...: "IntStruct(ob_digit)={self.ob_digit}, refcount={self.ob_refcnt}"

...: ).format(self=self)

...:

现在用42来做实验。在Python中,id方法会返回对象的内存地址:

In [10]: num = 42

In [11]: IntStruct.from_address(id(42))

Out[11]: IntStruct(ob_digit)=42, refcount=61

可以看到ob_digit指向了内存中的正确位置。但是这里只创建了一个对象,为什么引用次数是61呢?

事实证明,这是一个性能优化,Python使用了很多小的整数,如果为每一个数字都创建一个PyObject,会消耗掉不少内存。出于这个考虑,Python将一些常用的数字做了单例实现,这样每个数字在内存中只有一份拷贝。换句话说,如果在这个范围内创建一个新的Python整数时,只是创建了一个对该数值对象的引用。

In [16]: x = 42

In [17]: y = 42

In [18]: id(x) == id(y)

Out[18]: True

上面的例子中,x和y都指向了同一个内存地址。在使用更大的数的时候,等式就不成立了

In [19]: x = 1234

In [20]: y = 1234

In [21]: id(x) == id(y)

Out[21]: False

Python解释器启动时候会创建很多的整数对象;可以看看这些对象的引用分布

%matplotlib osx

import matplotlib.pyplot as plt

import sys

plt.loglog(range(1000), [sys.getrefcount(i) for i in range(1000)])

plt.xlabel('integer value')

plt.ylabel('reference count')

Out[8]: Text(0,0.5,'reference count')

可以看到0被引用了数千次,一般情况下,引用的频率随着整数值的增加而减少。

再来看看ob_digit对应的值

In [8]: all(i == IntStruct.from_address(id(i)).ob_digit for i in range(256))

Out[8]: True

如果更细心一点,就可以发现,对于大于256的值,ob_digit就不能对应到正确的值了:在Objects/longobject.c中对数值有一些移位操作,这也是Python对一些大整数的处理方式。

比如

In [11]: 2 ** 100

Out[11]: 1267650600228229401496703205376

这个值显然是超过了long类型的范围了。

List类型

现在来看看一个更复杂的数据类型:List。同样能在Include/listobject.h中找到List类型的struct结构:

typedef struct {

PyObject_VAR_HEAD

PyObject **ob_item;

Py_ssize_t allocated;

} PyListObject;

和之前一样,得到有效的结构体如下:

typedef struct {

long ob_refcnt;

PyTypeObject *ob_type;

Py_ssize_t ob_size;

PyObject **ob_item;

long allocated;

} PyListObject;

其中PyObject **ob_item指向list的数据,ob_size指出list中数据的个数。

In [3]: class ListStruct(ctypes.Structure):

...: _fields_ = [("ob_refcnt", ctypes.c_long),

...: ("ob_type", ctypes.c_void_p),

...: ("ob_size", ctypes.c_ulong),

...: ("ob_item", ctypes.c_long), # PyObject** pointer cast t

...: o long

...: ("allocated", ctypes.c_ulong)]

...:

...: def __repr__(self):

...: return ("ListStruct(len={self.ob_size}, "

...: "refcount={self.ob_refcnt})").format(self=self)

试验一下

In [8]: L = [1, 2, 3, 4]

In [9]: ListStruct.from_address(id(L))

Out[9]: ListStruct(len=4, refcount=1)

为确保得到的结果是正确的,对这个list增加几个引用,看看会不会影响引用计数:

In [10]: tup = [L, L]

In [11]: ListStruct.from_address(id(L))

Out[11]: ListStruct(len=4, refcount=3)

使用ctypes可以创建由之前IntStruct对象组成的复合结构

In [20]: Lstruct = ListStruct.from_address(id(L))

In [21]: PtrArray = Lstruct.ob_size * ctypes.POINTER(IntStruct)

In [22]: L_values = PtrArray.from_address(Lstruct.ob_item)

看看每个元素的值

In [23]: [ptr[0] for ptr in L_values]

Out[23]:

[IntStruct(ob_digit=1, refcount=4705),

IntStruct(ob_digit=2, refcount=1102),

IntStruct(ob_digit=3, refcount=559),

IntStruct(ob_digit=4, refcount=726)]

NumPy的数组

同样的,我们来看看numpy中的数组。其C-API定义的结构见numpy/core/include/numpy/ndarraytypes.h,这里用的numpy版本是1.13.3,不同版本的结构可能有所不同。

In [25]: np.__version__

Out[25]: '1.13.3'

现在用ctypes来创建一个numpy数组的结构吧。

In [31]: class NumpyStruct(ctypes.Structure):

...: _fields_ = [("ob_refcnt", ctypes.c_long),

...: ("ob_type", ctypes.c_void_p),

...: ("ob_data", ctypes.c_long), # char* pointer cast to long

...: ("ob_ndim", ctypes.c_int),

...: ("ob_shape", ctypes.c_voidp),

...: ("ob_strides", ctypes.c_voidp)]

...:

...: @property

...: def shape(self):

...: return tuple((self.ob_ndim * ctypes.c_int64).from_address(self.ob_shape))

...:

...: @property

...: def strides(self):

...: return tuple((self.ob_ndim * ctypes.c_int64).from_address(self.ob_strides))

...:

...: def __repr__(self):

...: return ("NumpyStruct(shape={self.shape}, "

...: "refcount={self.ob_refcnt})").format(self=self)

新建一个numpy数组试试In [32]: x = np.random.random((10, 20)) In [33]: xstruct = NumpyStruct.from_address(id(x)) In [34]: xstruct Out[34]: NumpyStruct(shape=(10, 20), refcount=1)

可以看到已经拿到了正确的shape。现在看看引用计数的情况

In [35]: L = [x, x, x]

In [36]: xstruct

Out[36]: NumpyStruct(shape=(10, 20), refcount=4)

现在可以看看里面的数据了。

In [37]: x = np.arange(10)

In [38]: xstruct = NumpyStruct.from_address(id(x))

In [39]: size = np.prod(xstruct.shape)

In [40]: arraytype = size * ctypes.c_long

In [41]: data = arraytype.from_address(xstruct.ob_data)

In [42]: [d for d in data]

Out[42]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

上面的data变量存储了Numpy数组中定义的连续的内存块,可以改一下其中的值。

In [43]: x[4] = 555

In [44]: [d for d in data]

Out[44]: [0, 1, 2, 3, 555, 5, 6, 7, 8, 9]

上面的例子可以证明x和data指向了同一块连续内存。

比较Python的list和numpy的ndarray的内部结构,明显可以看出numpy的数据对于表示同类型的数据列表来说简单的多。

结语

Python很慢,正如上面所说,一个重要原因是类型的间接寻址,这也是Python对开发者友好的原因。同时,Python本身也提供了可用于破解Python对象的工具,通过使用这些工具可以解析CPython的一些内部行为。

阿里云青岛装 python 库里的东西慢的跟狗屎一样怎么办

修改hosts就好,毕竟拉取代码都是使用https的链接,你在hosts内添加对应域名条目指向219.76.4.14就可以,因为经过香港的直连缓存所以速度就笑渣会块很丛升稿多。

阿里云渗孝上外网慢这是很正常的,因为使用的是中国电信的出口。

python下不了是怎么回事?

管他为什么,直接不管他。源袭

然后下载一燃裂伏个anaconda,conda里面的所有都是自成一套,不受别的影响,这样就肯定没问题了呀。

下载anaconda千万别去官网下,超!级!慢!推荐从清华镜像源下皮携载,非!常!快!

腾讯云cospython大文件下载不下来

1、使用分片下载:将大文件分割成多个小块进行并行下载,以提高下载速度。可以参考文档中的示例代码:分块下载。

2、调整单次下载的最大字节数:默认情况下,单次汪顷缓下载的最大字节数为5MB。可以通过设置参数MaxThread来增加线程数或者PartSize来调整单个数据块的大小,从而提高下载速度。

3、检查网络状况:下载大文件需要消耗大量的带宽和网络资源。如果您的网络连接不稳定,可能会导致下载速度变乎庆慢或者下载失败。建议您困模检查网络状况,并且避免在高峰期进行下载操作。

(责任编辑:IT教学网)

更多

推荐数据库文章