Python FTPLib demasiado lento?
-
08-07-2019 - |
Pregunta
He estado jugando con la biblioteca FTP de Python y estoy empezando a pensar que es demasiado lento en comparación con el uso de un archivo de script en DOS. Ejecuto sesiones donde descargo miles de archivos de datos (creo que tengo más de 8 millones en este momento). Mi observación es que el proceso de descarga parece tardar de cinco a diez veces más en Python que en comparación con el uso de los comandos ftp en el shell de DOS.
Como no quiero que nadie arregle mi código, no he incluido ninguno. Estoy más interesado en entender si mi observación es válida o si necesito jugar más con los argumentos.
Solución
FTPLib se implementa en Python mientras que su "DOS Script" es en realidad un script que llama a un comando compilado. Ejecutar este comando es probablemente más rápido que interpretar el código Python. Si es demasiado lento para usted, sugiero llamar al comando DOS desde Python usando el módulo de subproceso .
Otros consejos
FTPlib puede no ser la API de Python más limpia, no creo que sea tan malo que se ejecute diez veces más lento que un script de shell de DOS.
A menos que no proporcione ningún código para comparar, por ejemplo, su shell y su fragmento de Python para lotes de archivos dl 5000, no puedo ver cómo podemos ayudarlo.
El problema de velocidad está probablemente en su código. FTPlib no es 10 veces más lento.
defina el tamaño de bloque junto con el storbinario de la conexión ftp, por lo que obtendrá una conexión 1.5-3.0x más rápida que FTP Filezilla :)
from ftplib import FTP
USER = "Your_user_id"
PASS = "Your_password"
PORT = 21
SERVER = 'ftp.billionuploads.com' #use FTP server name here
ftp = FTP()
ftp.connect(SERVER, PORT)
ftp.login(USER, PASS)
try:
file = open(r'C:\Python27\1.jpg','rb')
ftp.storbinary('STOR ' + '1.jpg', file,102400) #here we store file in 100kb blocksize
ftp.quit()
file.close()
print "File transfered"
except:
print "Error in File transfering"
import ftplib
import time
ftp = ftplib.FTP("localhost", "mph")
t0 = time.time()
with open('big.gz.sav', 'wb') as f:
ftp.retrbinary('RETR ' + '/Temp/big.gz', f.write)
t1 = time.time()
ftp.close()
ftp = ftplib.FTP("localhost", "mph")
t2 = time.time()
ftp.retrbinary('RETR ' + '/Temp/big.gz', lambda x: x)
t3 = time.time()
print "saving file: %f to %f: %f delta" % (t0, t1, t1 - t0)
print "not saving file: %f to %f: %f delta" % (t2, t3, t3 - t2)
Entonces, tal vez no 10x. Pero mis ejecuciones de guardar este archivo están por encima de 160 en una computadora portátil con un núcleo de 1.8 Ghz core i7 y 8 GB de ram (debería ser excesivo) con Windows 7. Un cliente nativo lo hace a los 100. Sin el archivo guardado, tengo poco menos de 70 años.
Llegué a esta pregunta porque he visto un rendimiento lento con ftplib en una Mac (volveré a ejecutar esta prueba nuevamente una vez que tenga acceso a esa máquina nuevamente). Si bien la sincronización con las escrituras podría ser una buena idea en este caso, en una red real sospecho que sería una ganancia mucho menor.
deshabilite ftplib y ejecute ftp a través de Msdos
os.system('FTP -v -i -s:C:\\ndfd\\wgrib2\\ftpscript.txt')
dentro de ftpscript.txt
open example.com
username
password
!:--- FTP commands below here ---
lcd c:\MyLocalDirectory
cd public_html/MyRemoteDirectory
binary
mput "*.*"
disconnect
bye
Un tamaño de bloque más grande no siempre es el óptimo. Por ejemplo, al cargar el mismo archivo de 167 MB a través de la red cableada al mismo servidor FTP, obtuve los siguientes tiempos en segundos para varios tamaños de bloque:
Blocksize Time
102400 40
51200 30
25600 28
32768 30
24576 31
19200 34
16384 61
12800 144
En esta configuración, el óptimo era alrededor de 32768 (4x8192).
Pero si usé la conexión inalámbrica, obtuve estos tiempos:
Blocksize Time
204800 78
102400 76
51200 79
25600 76
32768 89
24576 86
19200 75
16384 166
12800 178
default 223
En este caso, hubo varios valores óptimos de tamaño de bloque, todos diferentes de 32768.