Pandas: read_csv() 3.5X Lebih Lambat di Pandas 0.23.4 di Python 3.7.1 vs Pandas 0.22.0 di Python 3.5.2

Dibuat pada 5 Nov 2018  ·  56Komentar  ·  Sumber: pandas-dev/pandas

Contoh Kode, contoh yang dapat disalin jika memungkinkan

import io
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(1000000, 10), columns=('COL{}'.format(i) for i in range(10)))
csv = io.StringIO(df.to_csv(index=False))
df2 = pd.read_csv(csv)

Deskripsi masalah

pd.read_csv() menggunakan _libs.parsers.TextReader read() metode 3,5X lebih lambat pada Pandas 0.23.4 pada Python 3.7.1 dibandingkan dengan Pandas 0.22.0 pada Python 3.5.2.

 4244 function calls (4210 primitive calls) in 10.273 seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1   10.202   10.202   10.204   10.204 {method 'read' of 'pandas._libs.parsers.TextReader' objects}
        1    0.039    0.039    0.039    0.039 internals.py:5017(_stack_arrays)
        1    0.011    0.011   10.262   10.262 parsers.py:414(_read)
        1    0.011    0.011   10.273   10.273 <string>:1(<module>)
        1    0.004    0.004    0.004    0.004 parsers.py:1685(__init__)
      321    0.001    0.000    0.002    0.000 common.py:811(is_integer_dtype)

Keluaran yang diharapkan

3229 function calls (3222 primitive calls) in 2.944 seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    2.881    2.881    2.882    2.882 {method 'read' of 'pandas._libs.parsers.TextReader' objects}
        1    0.045    0.045    0.045    0.045 internals.py:4801(_stack_arrays)
        1    0.010    0.010    2.944    2.944 parsers.py:423(_read)
        1    0.004    0.004    0.004    0.004 parsers.py:1677(__init__)
      320    0.001    0.000    0.001    0.000 common.py:777(is_integer_dtype)
        1    0.001    0.001    0.001    0.001 {method 'close' of 'pandas._libs.p

Keluaran pd.show_versions() -- Latst Python 3.7.1 Pandas 0.23.4 : Slow Read CSV

VERSI TERINSTAL

komit: Tidak ada
python: 3.7.1.final.0
python-bit: 64
OS: Windows
Rilis OS: 2008ServerR2
mesin: AMD64
prosesor: Intel64 Family 6 Model 63 Stepping 2, GenuineIntel
urutan byte: sedikit
LC_ALL: Tidak ada
LANG: Tidak ada
LOKAL: Tidak ada. Tidak ada

panda: 0.23.4
tes: 3.9.2
pip: 18,1
setuptools: 40.4.3
Siton: 0,29
numpy: 1.15.3
sip: 1.1.0
pyarrow: 0.11.0
xarray: 0.10.9
IPython: 7.0.1
sphinx: 1.8.1
kue: 0.5.0
dateutil: 2.7.3
pytz: 2018.5
blok: 1.6.1
kemacetan: 1.2.1
tabel: 3.4.4
jumlah ekspr: 2.6.8
bulu: Tidak ada
matplotlib: 3.0.0
openpyxl: 2.5.9
xlrd: 1.1.0
xlwt: 1.3.0
xlsxpenulis: Tidak ada
lxml: 4.2.5
bs4: 4.6.3
html5lib: 1.0.1
sqlalchemy: 1.2.12
pymysql: Tidak ada
psycopg2: Tidak ada
jinja2: 2.10
s3fs: Tidak ada
parket cepat: 0.16
pandas_gbq: Tidak ada
pandas_datareader: Tidak ada

Keluaran pd.show_versions() -- Older Python 3.5.2 Pandas 0.22.0 : Fast Read CSV

VERSI TERINSTAL

komit: Tidak ada
python: 3.5.2.final.0
python-bit: 64
OS: Windows
Rilis OS: 7
mesin: AMD64
prosesor: Intel64 Family 6 Model 63 Stepping 2, GenuineIntel
urutan byte: sedikit
LC_ALL: Tidak ada
LANG: Tidak ada
LOKAL: Tidak ada. Tidak ada

panda: 0.22.0
uji coba: 3.5.0
pip: 9.0.3
setuptools: 20.10.1
Cython: 0.28.1
numpy: 1.14.2
sip: 1.0.1
pyarrow: 0.9.0
xarray: 0.10.2
IPython: 6.3.0
sphinx: 1.7.2
kue: 0.5.0
dateutil: 2.7.2
pytz: 2018.3
blok: Tidak ada
kemacetan: 1.2.1
tabel: 3.4.2
angka: 2.6.4
bulu: 0.4.0
matplotlib: 2.2.2
openpyxl: 2.5.1
xlrd: 1.1.0
xlwt: 1.3.0
xlsxpenulis: Tidak ada
lxml: 4.2.1
bs4: 4.6.0
html5lib: 0.9999999
sqlalchemy: 1.2.6
pymysql: Tidak ada
psycopg2: Tidak ada
jinja2: 2.10
s3fs: Tidak ada
parket cepat: 0.1.5
pandas_gbq: Tidak ada
pandas_datareader: Tidak ada

IO CSV Performance

Komentar yang paling membantu

Saya membandingkan pernyataan df2 = pd.read_csv(csv) pada Python 3.7.0a3 dan a4 di profiler Visual Studio. Pelakunya adalah fungsi isdigit dipanggil dalam modul ekstensi parsers . Pada 3.7.0a3 fungsinya cepat pada ~8% sampel. Pada 3.7.0a4 fungsinya lambat pada ~64% sampel karena memanggil fungsi _isdigit_l , yang tampaknya memperbarui dan memulihkan lokal di utas saat ini setiap kali...

3.7.0a3:
Function Name   Inclusive Samples   Exclusive Samples   Inclusive Samples % Exclusive Samples % Module Name
 + [parsers.cp37-win_amd64.pyd] 705 347 28.52%  14.04%  parsers.cp37-win_amd64.pyd
   isdigit  207 207 8.37%   8.37%   ucrtbase.dll
 - _errno   105 39  4.25%   1.58%   ucrtbase.dll
   toupper  24  24  0.97%   0.97%   ucrtbase.dll
   isspace  21  21  0.85%   0.85%   ucrtbase.dll
   [python37.dll]   1   1   0.04%   0.04%   python37.dll
3.7.0a4:
Function Name   Inclusive Samples   Exclusive Samples   Inclusive Samples % Exclusive Samples % Module Name
 + [parsers.cp37-win_amd64.pyd] 8,613   478 83.04%  4.61%   parsers.cp37-win_amd64.pyd
 + isdigit  6,642   208 64.04%  2.01%   ucrtbase.dll
 + _isdigit_l   6,434   245 62.03%  2.36%   ucrtbase.dll
 + _LocaleUpdate::_LocaleUpdate 5,806   947 55.98%  9.13%   ucrtbase.dll
 + __acrt_getptd    2,121   1,031   20.45%  9.94%   ucrtbase.dll
   FlsGetValue  647 647 6.24%   6.24%   KernelBase.dll
 - RtlSetLastWin32Error 296 235 2.85%   2.27%   ntdll.dll
   _guard_dispatch_icall_nop    101 101 0.97%   0.97%   ucrtbase.dll
   GetLastError 46  46  0.44%   0.44%   KernelBase.dll
 + __acrt_update_multibyte_info 1,475   246 14.22%  2.37%   ucrtbase.dll
 - __crt_state_management::get_current_state_index  1,229   513 11.85%  4.95%   ucrtbase.dll
 + __acrt_update_locale_info    1,263   235 12.18%  2.27%   ucrtbase.dll
 - __crt_state_management::get_current_state_index  1,028   429 9.91%   4.14%   ucrtbase.dll
   _ischartype_l    383 383 3.69%   3.69%   ucrtbase.dll

Semua 56 komentar

Bisakah Anda membandingkan hanya perubahan python, dan hanya perubahan panda secara terpisah?

Bisakah Anda membandingkan hanya perubahan python, dan hanya perubahan panda secara terpisah?

Ya, apakah ada versi lama Panda di Python 3.7.1? Saya kira saya dapat mencoba versi panda yang lebih baru di Python lama.

Saya pikir 0.23.2 adalah versi panda pertama yang mendukung 3.7

Pada Senin, 5 November 2018 pukul 13:15 Gagi [email protected] menulis:

Bisakah Anda membandingkan hanya perubahan python, dan hanya perubahan panda
terpisah?

Ya, apakah ada versi lama Panda di Python 3.7.1? Saya kira saya bisa mencoba
versi panda yang lebih baru di Python lama.


Anda menerima ini karena Anda berkomentar.
Balas email ini secara langsung, lihat di GitHub
https://github.com/pandas-dev/pandas/issues/23516#issuecomment-435999395 ,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/ABQHIm27-U5HB6S2JcM2DPtr6YzlPC90ks5usI48gaJpZM4YPD2Y
.

Saya menjalankan tes pada tumpukan Python 3.5 yang lebih lama dengan Pandas versi terbaru 0.23.4 tetapi dengan banyak versi modul lain yang lebih lama dan tampaknya berjalan lebih cepat pada Python 3.5. Sekarang, saya tidak yakin apakah pandanya langsung di python 3.7.1 atau salah satu dependensinya.

Apakah metode _read() parser bergantung pada beberapa perpustakaan lain yang mungkin menjadi penyebabnya?

 %prun df2 = pd.read_csv(csv)
         5154 function calls (5041 primitive calls) in 2.004 seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    1.960    1.960    1.962    1.962 {method 'read' of 'pandas._libs.parsers.TextReader' objects}
        1    0.030    0.030    0.030    0.030 internals.py:5017(_stack_arrays)
        1    0.006    0.006    2.004    2.004 parsers.py:414(_read)
        1    0.003    0.003    0.003    0.003 parsers.py:1685(__init__)
      321    0.001    0.000    0.001    0.000 common.py:811(is_integer_dtype)
      518    0.000    0.000    0.000    0.000 common.py:1835(_get_dtype_type)

Menginstal Python 3.5 Stack Dengan panda terbaru 0.23.4:

VERSI TERINSTAL

komit: Tidak ada
python: 3.5.2.final.0
python-bit: 64
OS: Windows
Rilis OS: 10
mesin: AMD64
prosesor: Intel64 Family 6 Model 158 Stepping 10, GenuineIntel
urutan byte: sedikit
LC_ALL: Tidak ada
LANG: Tidak ada
LOKAL: Tidak ada. Tidak ada

panda: 0.23.4
uji coba: 3.5.0
pip: 18.0
setuptools: 38.6.0
Cython: 0.28.1
numpy: 1.14.2
sip: 1.0.1
pyarrow: 0.10.0
xarray: 0.10.2
IPython: 6.3.0
sphinx: 1.7.2
kue: 0.5.0
dateutil: 2.7.2
pytz: 2018.3
blok: 1.5.1
kemacetan: 1.2.1
tabel: 3.4.2
angka: 2.6.4
bulu: 0.4.0
matplotlib: 2.2.2
openpyxl: 2.5.1
xlrd: 1.1.0
xlwt: 1.3.0
xlsxpenulis: Tidak ada
lxml: 4.2.1
bs4: 4.6.0
html5lib: 0.9999999
sqlalchemy: 1.2.6
pymysql: Tidak ada
psycopg2: Tidak ada
jinja2: 2.10
s3fs: Tidak ada
parket cepat: 0.1.5
pandas_gbq: Tidak ada
pandas_datareader: Tidak ada

<\detail>

Menariknya jika saya menentukan float_precision='round_trip' saya mendapatkan kecepatan parsing yang sama. Jika saya menentukan 'tinggi' atau Tidak Ada maka kembali ke perbedaan 3,5x yang sama.

__Python 3.7.1__

 %prun df2 = pd.read_csv(csv, float_precision='round_trip')
         4320 function calls (4286 primitive calls) in 4.074 seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    3.862    3.862    3.864    3.864 {method 'read' of 'pandas._libs.parsers.TextReader' objects}
        1    0.168    0.168    4.074    4.074 <string>:1(<module>)
        1    0.030    0.030    0.030    0.030 internals.py:5017(_stack_arrays)
        1    0.006    0.006    3.906    3.906 parsers.py:414(_read)
        1    0.003    0.003    0.003    0.003 parsers.py:1685(__init__)
      321    0.001    0.000    0.002    0.000 common.py:811(is_integer_dtype)
      516    0.000    0.000    0.001    0.000 common.py:1835(_get_dtype_type)
      952    0.000    0.000    0.000    0.000 {built-in method builtins.isinstance}

__Python 3.5.2__

 %prun df2 = pd.read_csv(csv, float_precision='round_trip')
         4582 function calls (4545 primitive calls) in 3.716 seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    3.665    3.665    3.667    3.667 {method 'read' of 'pandas._libs.parsers.TextReader' objects}
        1    0.031    0.031    0.031    0.031 internals.py:5017(_stack_arrays)
        1    0.006    0.006    3.710    3.710 parsers.py:414(_read)
        1    0.006    0.006    3.716    3.716 <string>:1(<module>)
        1    0.003    0.003    0.003    0.003 parsers.py:1685(__init__)
      321    0.001    0.000    0.001    0.000 common.py:811(is_integer_dtype)
      518    0.000    0.000    0.001    0.000 common.py:1835(_get_dtype_type)

Menambahkan titik data lain. Jika saya menentukan mesin 'python'. Sepertinya di Python 3.7.1 pandas._libs.lib.maybe_convert_numeric 3X lebih lambat daripada di Python di 3.5.2

Mungkinkah ini karena versi cython?

__Python 3.7.1__

%prun df2 = pd.read_csv(csv, engine='python')
         7003613 function calls (7003575 primitive calls) in 14.411 seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
       10    9.698    0.970    9.698    0.970 {pandas._libs.lib.maybe_convert_numeric}
  1000004    3.221    0.000    3.221    0.000 {built-in method builtins.next}
        1    0.386    0.386    4.066    4.066 parsers.py:2926(_get_lines)
        1    0.263    0.263   14.399   14.399 parsers.py:1029(read)
        4    0.154    0.038    0.247    0.062 parsers.py:2738(_remove_empty_lines)
  1000002    0.138    0.000    3.359    0.000 parsers.py:2681(_next_iter_line)
  2000072    0.125    0.000    0.125    0.000 {method 'append' of 'list' objects}
        1    0.116    0.116    0.116    0.116 {pandas._libs.lib.to_object_array}
  1000001    0.103    0.000    0.138    0.000 parsers.py:2869(<genexpr>)
2000130/2000117    0.069    0.000    0.069    0.000 {built-in method builtins.len}
       14    0.067    0.005    0.204    0.015 {built-in method builtins.max}

__Python 3.5.2__

 %prun df2 = pd.read_csv(csv, engine='python')
         7004040 function calls (7004000 primitive calls) in 8.411 seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
  1000003    3.662    0.000    3.662    0.000 {built-in method builtins.next}
       10    3.270    0.327    3.270    0.327 {pandas._libs.lib.maybe_convert_numeric}
        1    0.378    0.378    4.492    4.492 parsers.py:2926(_get_lines)
        1    0.263    0.263    8.398    8.398 parsers.py:1029(read)
        4    0.167    0.042    0.245    0.061 parsers.py:2738(_remove_empty_lines)
  1000002    0.141    0.000    3.803    0.000 parsers.py:2681(_next_iter_line)
        1    0.128    0.128    0.128    0.128 {pandas._libs.lib.to_object_array}
  2000067    0.109    0.000    0.109    0.000 {method 'append' of 'list' objects}
  1000001    0.108    0.000    0.133    0.000 parsers.py:2869(<genexpr>)
       14    0.060    0.004    0.193    0.014 {built-in method builtins.max}

Angka terakhir ini dengan versi panda apa?

Angka terakhir ini dengan versi panda apa?

Mereka berdua Panda 0.23.4

Saya mencoba membangun versi Pandas terbaru dari sumber di Python 3.7.1 dan masih mendapatkan kinerja yang lebih lambat. Apakah ada flag build/compile/cython yang dapat saya atur untuk mengoptimalkan parser?

seluruh masalah kinerja hanyalah tanda presisi

Anda dapat memilih presisi yang lebih tinggi tetapi membutuhkan lebih banyak waktu; ini jarang berguna

seluruh masalah kinerja hanyalah tanda presisi

Anda dapat memilih presisi yang lebih tinggi tetapi membutuhkan lebih banyak waktu; ini jarang berguna

Saya mencoba ketiga flag float_precision= dan untuk 'tinggi' dan Tidak ada pelambatan 3,5x masih ada di Python 3.7.1 vs python 2.5.2.

Saya juga mencoba menentukan float_format= di pd.to_csv() dan saya masih melihat kesenjangan 3,5x konsisten yang sama.

Bisakah Anda mereproduksi dengan Python 3.6?

Saya harus mengulangi perbedaan perf ini pada versi Pandas 0.23.4 yang sama hanya versi Python yang berbeda.

apakah ada cara untuk menentukan 'xstrtod', atau apakah itu ditentukan oleh float_precision=None?

Saya tidak melihat perubahan kinerja antara 'tinggi' dan Tidak Ada.

Adakah yang bisa mereproduksi ini di Python 3.7.1? Saya menguji kode di atas pada Python 3.7.0 menggunakan interpreter interaktif Python.org dan tampaknya berjalan lebih cepat daripada di instalasi 3.7.1 lokal saya.

Pasti ada sesuatu. Saya melakukan perbandingan berdampingan membaca file CSV yang sama pada disk. Python 3.5 membaca pada 111 MB/dtk dan Python 3.7 membaca hanya pada 28 MB/Detik dari SSD yang sama. Keduanya menjalankan Pandas 0.23.4.

Bisakah Python 3.7 mengubah sesuatu di sistem I/O mereka?

__Python 3.5.2 & Pandas 0.23.4__

In [38]: %timeit pd.read_csv(r'out.csv', float_precision='high')
1.86 s ± 13.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

__Python 3.7.1 & Pandas 0.23.4__

In [17]: %timeit pd.read_csv(r'out.csv', float_precision='high')
7.97 s ± 19 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

image

Saya tidak melihat perbedaan yang Anda lihat

Python 3.5.6 |Anaconda, Inc.| (default, Aug 26 2018, 16:30:03)
Type 'copyright', 'credits' or 'license' for more information
IPython 6.5.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import pandas as pd

In [2]: pd.__version__
Out[2]: '0.23.4'

In [3]: %time _ = pd.read_csv('out.csv', float_precision='high')
CPU times: user 2.59 s, sys: 214 ms, total: 2.81 s
Wall time: 2.73 s

3.7

Python 3.7.1 (default, Oct 23 2018, 14:07:42)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.1.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import pandas as pd

In [2]: pd.__version__
Out[2]: '0.23.4'

In [3]: %time _ = pd.read_csv('out.csv', float_precision='high')
CPU times: user 2.61 s, sys: 211 ms, total: 2.82 s
Wall time: 2.74 s

Keduanya menggunakan paket Anaconda.

Tom, terima kasih telah menjalankan benchmark ini. Bisakah Anda memposting pd.show_versions() Anda? Saya ingin membuat ulang tumpukan Anda persis untuk melakukan beberapa pengujian lagi.

3.5

INSTALLED VERSIONS
------------------
commit: None
python: 3.5.6.final.0
python-bits: 64
OS: Darwin
OS-release: 17.7.0
machine: x86_64
processor: i386
byteorder: little
LC_ALL: None
LANG: en_US.UTF-8
LOCALE: en_US.UTF-8

pandas: 0.23.4
pytest: None
pip: 10.0.1
setuptools: 40.2.0
Cython: None
numpy: 1.15.2
scipy: None
pyarrow: None
xarray: None
IPython: 6.5.0
sphinx: None
patsy: None
dateutil: 2.7.3
pytz: 2018.5
blosc: None
bottleneck: None
tables: None
numexpr: None
feather: None
matplotlib: None
openpyxl: None
xlrd: None
xlwt: None
xlsxwriter: None
lxml: None
bs4: None
html5lib: None
sqlalchemy: None
pymysql: None
psycopg2: None
jinja2: None
s3fs: None
fastparquet: None
pandas_gbq: None
pandas_datareader: None

3.7:

INSTALLED VERSIONS
------------------
commit: None
python: 3.7.1.final.0
python-bits: 64
OS: Darwin
OS-release: 17.7.0
machine: x86_64
processor: i386
byteorder: little
LC_ALL: None
LANG: en_US.UTF-8
LOCALE: en_US.UTF-8

pandas: 0.23.4
pytest: None
pip: 18.1
setuptools: 40.5.0
Cython: None
numpy: 1.15.4
scipy: None
pyarrow: None
xarray: None
IPython: 7.1.1
sphinx: None
patsy: None
dateutil: 2.7.5
pytz: 2018.7
blosc: None
bottleneck: None
tables: None
numexpr: None
feather: None
matplotlib: None
openpyxl: None
xlrd: None
xlwt: None
xlsxwriter: None
lxml: None
bs4: None
html5lib: None
sqlalchemy: None
pymysql: None
psycopg2: None
jinja2: None
s3fs: None
fastparquet: None
pandas_gbq: None
pandas_datareader: None

Saya mencoba beberapa instalasi python baru yang berbeda di windows. Setiap instalasi Python 3.7 32 atau 64 bit dengan Pandas 0.23.4 pip diinstal menghasilkan kecepatan parsing CSV yang lebih lambat. Untuk bersenang-senang saya mencoba Menginstal instalasi Python 3.6.7 yang baru dan sekali lagi mem-parsing CSV yang sama 3X lebih cepat.

Apakah ada orang yang bisa menguji ini di Windows 10 dan Python 3.7.1? 😕

cc @chris-b1 jika Anda dapat menguji di Windows

Memang, saya dapat mengkonfirmasi bahwa ada pelambatan 3,5X saat menggunakan Python 3.7.1 di Windows 10.

Ketika saya menggunakan Python 3.5.6, kinerjanya tidak berubah dari 0.22.0 menjadi 0.23.4 .

Pengamatan ini konsisten dengan apa yang diamati oleh pandas .

Di windows 10, python 3.6 dan python 3.7 Saya juga mencatat perlambatan yang nyata.

(py36) PS C:\Users\ttttt> ipython
Python 3.6.4 | packaged by conda-forge | (default, Dec 24 2017, 10:11:43) [MSC v.1900 64 bit (AMD64)]
Type 'copyright', 'credits' or 'license' for more information
IPython 7.1.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import pandas as pd

In [2]: %time _ = pd.read_csv('out.csv', float_precision='high')
Wall time: 7.03 s

In [3]: %time _ = pd.read_csv('out.csv')
Wall time: 7.04 s

ular piton 3.7

```python
(py37) PS C:\Users\ttttt> ipython
Python 3.7.1 (default, 28 Okt 2018, 08:39:03) [MSC v.1912 64 bit (AMD64)]
Ketik 'hak cipta', 'kredit' atau 'lisensi' untuk informasi lebih lanjut
IPython 7.1.1 -- Python Interaktif yang disempurnakan. Jenis '?' untuk bantuan.

Di [1]: impor panda sebagai pd
Dalam [2]: df = pd.DataFrame(np.random.randn(1000000, 10), column=('COL{}'.format(i) for i in range(10)))
Di [6]: df.to_csv('out.csv')
Dalam [7]: %time _ = pd.read_csv('out.csv', float_precision='high')
Waktu dinding: 29,4 detik

Dalam [8]: %time _ = pd.read_csv('out.csv')
Waktu dinding: 31,3 detik
````

Untuk orang-orang di windows, bagaimana Anda menginstal panda? Dari paket sumber, roda, atau conda? Dan jika conda, dari default atau dari conda-forge?

Di sini conda-forge:

PS C:\Users\ttttt> activate py37
(py37) PS C:\Users\ttttt> conda install ipython pandas
Solving environment: done
## Package Plan ##
  environment location: C:\Miniconda\envs\py37
  added / updated specs:
    - ipython
    - pandas
The following packages will be downloaded:
    package                    |            build
    ---------------------------|-----------------
    ipython-7.1.1              |py37h39e3cac_1000         1.1 MB  conda-forge
    wcwidth-0.1.7              |             py_1          17 KB  conda-forge
    six-1.11.0                 |        py37_1001          21 KB  conda-forge
    pytz-2018.7                |             py_0         226 KB  conda-forge
    icc_rt-2017.0.4            |       h97af966_0         8.0 MB
    pygments-2.2.0             |             py_1         622 KB  conda-forge
    pickleshare-0.7.5          |        py37_1000          12 KB  conda-forge
    certifi-2018.10.15         |        py37_1000         137 KB  conda-forge
    backcall-0.1.0             |             py_0          13 KB  conda-forge
    mkl_random-1.0.1           |   py37h77b88f5_1         267 KB
    decorator-4.3.0            |             py_0          10 KB  conda-forge
    numpy-1.15.4               |   py37ha559c80_0          36 KB
    mkl-2019.0                 |              118       178.1 MB
    pandas-0.23.4              |py37h830ac7b_1000         8.7 MB  conda-forge
    prompt_toolkit-2.0.7       |             py_0         218 KB  conda-forge
    python-dateutil-2.7.5      |             py_0         218 KB  conda-forge
    colorama-0.4.0             |             py_0          15 KB  conda-forge
    mkl_fft-1.0.6              |   py37hdbbee80_0         120 KB
    jedi-0.13.1                |        py37_1000         228 KB  conda-forge
    intel-openmp-2019.0        |              118         1.7 MB
    parso-0.3.1                |             py_0          59 KB  conda-forge
    traitlets-4.3.2            |        py37_1000         130 KB  conda-forge
    ipython_genutils-0.2.0     |             py_1          21 KB  conda-forge
    numpy-base-1.15.4          |   py37h8128ebf_0         3.9 MB
    blas-1.0                   |              mkl           6 KB
    ------------------------------------------------------------
                                           Total:       203.7 MB

Terima kasih @toniatop. Bisakah Anda membuat beberapa lingkungan hanya dengan default untuk melihat apakah itu masalah dengan bagaimana itu dikompilasi untuk conda-forge?

Ulangi semuanya memaksa --channel anaconda, hasil yang sama.

cc @jjhelmus ada pemikiran tentang
https://github.com/pandas-dev/pandas/issues/23516#issuecomment -436958298? Tldrnya itu

  • pd.read_csv 3-4x lebih lambat pada python 3.7 vs. python 3.6
  • pelambatannya (tampaknya) hanya windows
  • diamati pada paket dari conda-forge dan default

Saya juga telah menguji ini dengan roda yang dibuat sebelumnya dari: https://www.lfd.uci.edu/~gohlke/pythonlibs/ Dengan hasil yang sama.

Saya juga menjalankan source build kode GitHub terbaru dengan python setup.py bdist_wheel dengan python 3.7.1 dan mendapatkan hasil yang sama seperti itu.

Saya ingin tahu apakah sesuatu dalam skrip build telah berubah atau beberapa flag kompilasi di windows.

Saya juga menjalankan source build kode GitHub terbaru dengan python setup.py bdist_wheel dengan python 3.7.1 dan mendapatkan hasil yang sama seperti itu.

Apakah Anda juga mencoba membangun dari sumber dengan 3.6?

Saya akan mencoba membangun dengan python 3.6.7 hari ini. Saya juga akan menggunakan cython versi terbaru jika itu penyebabnya.

Terima kasih untuk semua orang yang mengkonfirmasi ini di windows.

Saya hanya membangun kembali versi Pandas terbaru (0.23.4+) dari sumber dengan Cython 0.29 terbaru di Python 3.6.7 di Windows 10 dan kecepatan parsing adalah _fast_. Jadi sepertinya entah bagaimana terkait dengan Python 3.7 di windows. Tidak yakin apa itu bisa. Apakah sistem Python IO meneruskan data ke parser Cython/C? Apakah versi Python 3.7 dikompilasi tanpa optimasi?

Microsoft Windows [Version 10.0.16299.726]
(c) 2017 Microsoft Corporation. All rights reserved.

Python 3.6.7 (v3.6.7:6ec5cf24b7, Oct 20 2018, 13:35:33) [MSC v.1900 64 bit (AMD64)]
Type 'copyright', 'credits' or 'license' for more information
IPython 7.1.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import pandas as pd

In [2]: pd.show_versions()

INSTALLED VERSIONS
------------------
commit: None
python: 3.6.7.final.0
python-bits: 64
OS: Windows
OS-release: 10
machine: AMD64
processor: Intel64 Family 6 Model 158 Stepping 10, GenuineIntel
byteorder: little
LC_ALL: None
LANG: None
LOCALE: None.None

pandas: 0+unknown
pytest: None
pip: 10.0.1
setuptools: 39.0.1
Cython: 0.29
numpy: 1.15.4
scipy: None
pyarrow: None
xarray: None
IPython: 7.1.1
sphinx: None
patsy: None
dateutil: 2.7.5
pytz: 2018.7
blosc: None
bottleneck: 1.2.1
tables: None
numexpr: 2.6.8
feather: None
matplotlib: None
openpyxl: None
xlrd: None
xlwt: None
xlsxwriter: None
lxml: None
bs4: None
html5lib: None
sqlalchemy: None
pymysql: None
psycopg2: None
jinja2: None
s3fs: None
fastparquet: None
pandas_gbq: None
pandas_datareader: None
gcsfs: None

In [3]: import io

In [4]: import numpy as np

In [5]: %time df = pd.DataFrame(np.random.randn(1000000, 10), columns=('COL{}'.format(i) for i in range(10)))
Wall time: 207 ms

In [6]: %time csv = io.StringIO(df.to_csv(index=False))
Wall time: 13.2 s

In [7]: %time df2 = df2 = pd.read_csv(csv, float_precision='high')
Wall time: 1.96 s

Saya memposting Masalah yang menautkan ini di pelacak Masalah Python sehingga setidaknya mereka dapat melihatnya. Karena kinerjanya tampak bagus di Linux, saya berharap perbaikan kompilasi/konfigurasi dapat mengatasinya untuk Windows.

https://bugs.python.org/issue35195

Hanya untuk mencoret tersangka yang masuk akal dari daftar - versi MSVC tampaknya tidak masalah.

# builds with MSVC 2017 with python 3.7 (assuming installed)
λ python setup.py build_ext -i

# %timeit pd.read_csv('tmp.csv')
# 14.6 s ± 701 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

# builds with MSVC 2015
λ "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x64
λ python setup.py build_ext -i -f

# %timeit pd.read_csv('tmp.csv')
# 15.2 s ± 2.27 s per loop (mean ± std. dev. of 7 runs, 1 loop each)

Apakah versi Python 3.7 dikompilasi tanpa optimasi?

Tidak, ekstensi 3.7 terus dibuat dengan /Ox

Apakah perlambatan hanya dalam metode terkait IO?

Tampaknya masalahnya adalah penguraian float? Yang aneh karena xstrtod tidak (?) berinteraksi dengan Python sama sekali.

Faktanya, seperti yang dicatat oleh @dragoljub , menggunakan parser round_trip lebih cepat, yang TIDAK memanggil kembali ke python

In [1]: %timeit pd.read_csv('tmp.csv')
15.2 s ± 2.27 s per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [2]: %timeit pd.read_csv('tmp.csv', float_precision='precise')
18.9 s ± 984 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [3]: %timeit pd.read_csv('tmp.csv', float_precision='round_trip')
8.67 s ± 205 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

Saya menguji parsing 0-9 INT murni dan juga ~3.5X lebih lambat pada Python 3.7.1 di Windows. Jadi saya merasa masalah ini adalah dengan data yang masuk sebelum kita melakukan penguraian (float atau lainnya).

Saya juga melihat baris kode yang mencurigakan dipanggil di Python 3.7 tetapi tidak di 3.5.2:

{built-in method _thread.allocate_lock}

Mungkinkah ini sesuatu yang baru di Python 3.7.1 yang mengganggu parser? Apakah kita perlu merilis GIL secara berbeda untuk Python 3.7?

__Penyiapan Bingkai Data:__

import io
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randint(0, 9, (1000000, 10)), columns=('COL{}'.format(i) for i in range(10)))
csv = io.StringIO(df.to_csv(index=False))

```python
print(df.head().to_csv(index=False))

COL0,COL1,COL2,COL3,COL4,COL5,COL6,COL7,COL8,COL9
2,1,7,3,2,3,0,4,5,5
6,3,1,7,0,3,6,3,0,8
6,8,4,2,1,5,1,4,3,3
0,8,5,8,0,4,1,8,4,1
4,8,0,0,4,0,3,0,6,3

__Python 3.7.1 & Pandas 0.23.4 -- Slow__
```python
3676 function calls (3642 primitive calls) in 2.132 seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    2.075    2.075    2.075    2.075 {method 'read' of 'pandas._libs.parsers.TextReader' objects}
        1    0.039    0.039    0.039    0.039 internals.py:5017(_stack_arrays)
        1    0.009    0.009    2.132    2.132 parsers.py:414(_read)
        1    0.004    0.004    0.004    0.004 parsers.py:1685(__init__)
        1    0.000    0.000    0.000    0.000 {method 'close' of 'pandas._libs.parsers.TextReader' objects}
      161    0.000    0.000    0.000    0.000 common.py:811(is_integer_dtype)
      206    0.000    0.000    0.000    0.000 common.py:1835(_get_dtype_type)
      824    0.000    0.000    0.000    0.000 {built-in method builtins.isinstance}
        2    0.000    0.000    0.000    0.000 {built-in method nt.stat}
      8/2    0.000    0.000    0.001    0.000 <frozen importlib._bootstrap>:978(_find_and_load)
      4/3    0.000    0.000    0.000    0.000 base.py:255(__new__)
       76    0.000    0.000    0.000    0.000 base.py:61(is_dtype)
        2    0.000    0.000    0.001    0.000 {pandas._libs.lib.clean_index_list}
        1    0.000    0.000    2.132    2.132 {built-in method builtins.exec}
      462    0.000    0.000    0.000    0.000 {built-in method builtins.issubclass}
       41    0.000    0.000    0.000    0.000 {built-in method numpy.core.multiarray.array}
    89/78    0.000    0.000    0.000    0.000 {built-in method builtins.len}
       86    0.000    0.000    0.000    0.000 {built-in method builtins.hasattr}
      149    0.000    0.000    0.000    0.000 generic.py:7(_check)
        1    0.000    0.000    0.040    0.040 internals.py:4880(form_blocks)
      3/2    0.000    0.000    0.001    0.001 series.py:166(__init__)
       13    0.000    0.000    0.000    0.000 internals.py:3148(get_block_type)
      245    0.000    0.000    0.000    0.000 {built-in method builtins.getattr}
        7    0.000    0.000    0.000    0.000 {built-in method numpy.core.multiarray.empty}
       12    0.000    0.000    0.000    0.000 cast.py:971(maybe_cast_to_datetime)
        3    0.000    0.000    0.000    0.000 internals.py:237(mgr_locs)
        1    0.000    0.000    0.000    0.000 internals.py:3363(_rebuild_blknos_and_blklocs)
        8    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap>:157(_get_module_lock)
        2    0.000    0.000    0.000    0.000 {built-in method pandas._libs.lib.array_equivalent_object}
        2    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap>:882(_find_spec)
       12    0.000    0.000    0.000    0.000 series.py:4019(_sanitize_array)
        2    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap_external>:1356(find_spec)
       16    0.000    0.000    0.000    0.000 {built-in method _thread.allocate_lock}
        1    0.000    0.000    2.075    2.075 parsers.py:1846(read)
        2    0.000    0.000    0.000    0.000 missing.py:189(_isna_ndarraylike)
        2    0.000    0.000    0.000    0.000 {method 'reduce' of 'numpy.ufunc' objects}
        1    0.000    0.000    2.117    2.117 parsers.py:1029(read)
        1    0.000    0.000    2.132    2.132 parsers.py:542(parser_f)

__Python 3.5.2 & Pandas 0.23.4 -- Cepat__

%prun df2 = pd.read_csv(csv, float_precision=None)

2623 function calls (2616 primitive calls) in 0.661 seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.604    0.604    0.605    0.605 {method 'read' of 'pandas._libs.parsers.TextReader' objects}
        1    0.039    0.039    0.039    0.039 internals.py:4801(_stack_arrays)
        1    0.011    0.011    0.661    0.661 parsers.py:423(_read)
        1    0.004    0.004    0.004    0.004 parsers.py:1677(__init__)
        1    0.000    0.000    0.000    0.000 {method 'close' of 'pandas._libs.parsers.TextReader' objects}
      3/2    0.000    0.000    0.001    0.000 base.py:181(__new__)
      160    0.000    0.000    0.000    0.000 common.py:777(is_integer_dtype)
      186    0.000    0.000    0.000    0.000 common.py:1773(_get_dtype_type)
      622    0.000    0.000    0.000    0.000 {built-in method builtins.isinstance}
      108    0.000    0.000    0.000    0.000 {built-in method builtins.hasattr}
        1    0.000    0.000    0.605    0.605 parsers.py:1837(read)
        1    0.000    0.000    0.000    0.000 {pandas._libs.lib.clean_index_list}
      129    0.000    0.000    0.000    0.000 {built-in method builtins.getattr}
      118    0.000    0.000    0.000    0.000 generic.py:7(_check)
        1    0.000    0.000    0.039    0.039 internals.py:4645(form_blocks)
       10    0.000    0.000    0.000    0.000 cast.py:935(maybe_cast_to_datetime)
       61    0.000    0.000    0.000    0.000 dtypes.py:85(is_dtype)
      415    0.000    0.000    0.000    0.000 {built-in method builtins.issubclass}
        1    0.000    0.000    0.661    0.661 {built-in method builtins.exec}
        1    0.000    0.000    0.661    0.661 parsers.py:557(parser_f)

Saya juga menemukan perbaikan bug ini beberapa waktu lalu yang membuat beberapa perubahan pada pandas/src/parser/io.c PyGILState_Ensure() dipanggil, mungkin berinteraksi secara berbeda pada sistem windows dengan utas di Python 3.7.

11790

https://github.com/pandas-dev/pandas/pull/11790/files#diff -006bfcefd42c2be38e538fdd3219dbfdL125

Saya akan terkejut bahwa perubahan itu penting, tetapi saya bingung di sini, jadi mungkin! Kemungkinan lain adalah bahwa cython membuat beberapa penyesuaian pada logika threading untuk python 3.7 compat - sekali lagi, tidak akan berpikir itu masalahnya di sini, tetapi mungkin semacam interaksi yang buruk.
https://github.com/cython/cython/issues/1978

Saya akan terkejut bahwa perubahan itu penting, tetapi saya bingung di sini, jadi mungkin! Kemungkinan lain adalah bahwa cython membuat beberapa penyesuaian pada logika threading untuk python 3.7 compat - sekali lagi, tidak akan berpikir itu masalahnya di sini, tetapi mungkin semacam interaksi yang buruk.
cython/cython#1978

Informasi yang bagus. Saya hanya terkejut bahwa orang tidak melihat ini di Linux. Saya akan mencoba OSX berikutnya.

FYI pengaturan waktu saya di atas ada di OSX (tidak ada perlambatan)

Pada Jumat, Nov 9, 2018 at 02:16 Gagi [email protected] menulis:

Saya akan terkejut bahwa perubahan itu penting, tetapi saya bingung di sini, jadi mungkin!
Kemungkinan lain adalah cython membuat beberapa penyesuaian pada logika threading untuk
python 3.7 compat - sekali lagi, tidak akan berpikir itu masalahnya di sini, tapi
mungkin semacam interaksi yang buruk.
cython/cython#1978 https://github.com/cython/cython/issues/1978

Informasi yang bagus. Saya hanya terkejut bahwa orang tidak melihat ini di Linux. Sakit
coba OSX berikutnya.


Anda menerima ini karena Anda berkomentar.
Balas email ini secara langsung, lihat di GitHub
https://github.com/pandas-dev/pandas/issues/23516#issuecomment-437482307 ,
atau matikan utasnya
https://github.com/notifications/unsubscribe-auth/ABQHIl8M-FYdJ366ZxFHd1Rdur0sKyLEks5uteKAgaJpZM4YPD2Y
.

Sepertinya pelambatan pertama kali muncul di Python 3.7.0a4 :

>C:\python-3.7.0a3-amd64\python.exe -m cProfile -s tottime pandascsv.py
         235992 function calls (229477 primitive calls) in 21.525 seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
      200   11.316    0.057   11.316    0.057 {method 'astype' of 'numpy.ndarray' objects}
      100    6.596    0.066    6.596    0.066 {pandas._libs.writers.write_csv_rows}
        1    2.111    2.111    2.112    2.112 {method 'read' of 'pandas._libs.parsers.TextReader' objects}       
>C:\python-3.7.0a4-amd64\python.exe -m cProfile -s tottime pandascsv.py
         236639 function calls (230127 primitive calls) in 26.550 seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    9.849    9.849    9.850    9.850 {method 'read' of 'pandas._libs.parsers.TextReader' objects}
      200    8.766    0.044    8.766    0.044 {method 'astype' of 'numpy.ndarray' objects}
      100    6.469    0.065    6.469    0.065 {pandas._libs.writers.write_csv_rows}      

Sangat menarik. Saya akan mencoba Py 3.7.0a3 untuk mengonfirmasi ini di sistem saya. Apakah perbedaan antara 0a3 hingga 0a4 mudah ditemukan dari catatan rilis Python?

mudah ditemukan dari catatan rilis Python?

https://docs.python.org/3.7/whatsnew/changelog.html#python -3-7-0-alpha-4

Mungkin bpo-29240: Add a new UTF-8 mode: implementation of the PEP 540 ?

Lihat juga https://github.com/python/cpython/compare/v3.7.0a3...v3.7.0a4

Saya juga dapat mengkonfirmasi perubahan dari Python 3.7.0a3 ke 3.7.0a4 menunjukkan perlambatan pada sistem pengujian Win10 saya. Terima kasih telah menemukan saat pelambatan terjadi.

__Python 3.7.0a3 -- Parse Cepat__

 %prun df2 = pd.read_csv(csv)
         5781 function calls (5743 primitive calls) in 3.062 seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    2.953    2.953    2.955    2.955 {method 'read' of 'pandas._libs.parsers.TextReader' objects}
        1    0.063    0.063    0.063    0.063 internals.py:5017(_stack_arrays)
        1    0.016    0.016    3.052    3.052 parsers.py:414(_read)
        1    0.009    0.009    3.062    3.062 <string>:1(<module>)
        1    0.009    0.009    0.009    0.009 parsers.py:1685(__init__)
       32    0.004    0.000    0.004    0.000 {built-in method nt.stat}
        1    0.001    0.001    0.001    0.001 {method 'close' of 'pandas._libs.parsers.TextReader' objects}
      321    0.001    0.000    0.002    0.000 common.py:811(is_integer_dtype)
      516    0.001    0.000    0.001    0.000 common.py:1835(_get_dtype_type)
        7    0.001    0.000    0.001    0.000 {built-in method numpy.core.multiarray.empty}
       32    0.000    0.000    0.005    0.000 <frozen importlib._bootstrap_external>:1235(find_spec)
      988    0.000    0.000    0.000    0.000 {built-in method builtins.isinstance}
      163    0.000    0.000    0.000    0.000 common.py:1527(is_float_dtype)
      718    0.000    0.000    0.000    0.000 {built-in method builtins.issubclass}
      192    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap_external>:59(<listcomp>)
      192    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap_external>:57(_path_join)
        8    0.000    0.000    0.005    0.001 <frozen importlib._bootstrap_external>:1119(_get_spec)
      133    0.000    0.000    0.000    0.000 {built-in method builtins.getattr}
       68    0.000    0.000    0.000    0.000 generic.py:7(_check)

__Python 3.7.0a4 -- Parse Lambat__

 %prun df2 = pd.read_csv(csv)
         8007 function calls (7219 primitive calls) in 14.192 seconds

   Ordered by: internal time

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1   14.092   14.092   14.094   14.094 {method 'read' of 'pandas._libs.parsers.TextReader' objects}
        1    0.061    0.061    0.062    0.062 internals.py:5017(_stack_arrays)
        1    0.016    0.016   14.192   14.192 parsers.py:414(_read)
        1    0.008    0.008    0.008    0.008 parsers.py:1685(__init__)
       32    0.004    0.000    0.004    0.000 {built-in method nt.stat}
        1    0.001    0.001    0.001    0.001 {method 'close' of 'pandas._libs.parsers.TextReader' objects}
      321    0.001    0.000    0.002    0.000 common.py:811(is_integer_dtype)
      516    0.001    0.000    0.001    0.000 common.py:1835(_get_dtype_type)
        7    0.001    0.000    0.001    0.000 {built-in method numpy.core.multiarray.empty}
    115/4    0.000    0.000    0.001    0.000 abc.py:194(__subclasscheck__)
       32    0.000    0.000    0.005    0.000 <frozen importlib._bootstrap_external>:1322(find_spec)
 1324/988    0.000    0.000    0.002    0.000 {built-in method builtins.isinstance}
  937/725    0.000    0.000    0.002    0.000 {built-in method builtins.issubclass}
      163    0.000    0.000    0.000    0.000 common.py:1527(is_float_dtype)
      192    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap_external>:57(_path_join)
      192    0.000    0.000    0.000    0.000 <frozen importlib._bootstrap_external>:59(<listcomp>)
        8    0.000    0.000    0.005    0.001 <frozen importlib._bootstrap_external>:1206(_get_spec)
    89/78    0.000    0.000    0.000    0.000 {built-in method builtins.len}
      192    0.000    0.000    0.000    0.000 {built-in method builtins.getattr}

Saya mencoba bermain-main dengan pengaturan mode UTF-8 dengan variabel ENV dan argumen baris cmd di Windows dan tidak bisa mendapatkan kecepatan parsing yang lebih cepat di Python 3.7.0a4.

https://www.python.org/dev/peps/pep-0540/#proposal

Manfaat dari pendekatan paksaan lokal adalah membantu memastikan bahwa penanganan penyandian dalam modul ekstensi biner dan proses anak konsisten dengan penanganan penyandian Python. Keuntungan dari pendekatan Mode UTF-8 adalah memungkinkan aplikasi penyematan untuk mengubah perilaku penerjemah tanpa harus mengubah pengaturan lokal global proses.

Jadi, mungkinkah di suatu tempat ekstensi parser C kita dapat mengatur lokal ke UTF-8 dan masalah ini akan hilang di Windows? Saya berharap pengaturan variabel ENV akan memperbaiki masalah tetapi itu tidak membuat perbedaan dalam pengujian saya.

Saya membandingkan pernyataan df2 = pd.read_csv(csv) pada Python 3.7.0a3 dan a4 di profiler Visual Studio. Pelakunya adalah fungsi isdigit dipanggil dalam modul ekstensi parsers . Pada 3.7.0a3 fungsinya cepat pada ~8% sampel. Pada 3.7.0a4 fungsinya lambat pada ~64% sampel karena memanggil fungsi _isdigit_l , yang tampaknya memperbarui dan memulihkan lokal di utas saat ini setiap kali...

3.7.0a3:
Function Name   Inclusive Samples   Exclusive Samples   Inclusive Samples % Exclusive Samples % Module Name
 + [parsers.cp37-win_amd64.pyd] 705 347 28.52%  14.04%  parsers.cp37-win_amd64.pyd
   isdigit  207 207 8.37%   8.37%   ucrtbase.dll
 - _errno   105 39  4.25%   1.58%   ucrtbase.dll
   toupper  24  24  0.97%   0.97%   ucrtbase.dll
   isspace  21  21  0.85%   0.85%   ucrtbase.dll
   [python37.dll]   1   1   0.04%   0.04%   python37.dll
3.7.0a4:
Function Name   Inclusive Samples   Exclusive Samples   Inclusive Samples % Exclusive Samples % Module Name
 + [parsers.cp37-win_amd64.pyd] 8,613   478 83.04%  4.61%   parsers.cp37-win_amd64.pyd
 + isdigit  6,642   208 64.04%  2.01%   ucrtbase.dll
 + _isdigit_l   6,434   245 62.03%  2.36%   ucrtbase.dll
 + _LocaleUpdate::_LocaleUpdate 5,806   947 55.98%  9.13%   ucrtbase.dll
 + __acrt_getptd    2,121   1,031   20.45%  9.94%   ucrtbase.dll
   FlsGetValue  647 647 6.24%   6.24%   KernelBase.dll
 - RtlSetLastWin32Error 296 235 2.85%   2.27%   ntdll.dll
   _guard_dispatch_icall_nop    101 101 0.97%   0.97%   ucrtbase.dll
   GetLastError 46  46  0.44%   0.44%   KernelBase.dll
 + __acrt_update_multibyte_info 1,475   246 14.22%  2.37%   ucrtbase.dll
 - __crt_state_management::get_current_state_index  1,229   513 11.85%  4.95%   ucrtbase.dll
 + __acrt_update_locale_info    1,263   235 12.18%  2.27%   ucrtbase.dll
 - __crt_state_management::get_current_state_index  1,028   429 9.91%   4.14%   ucrtbase.dll
   _ischartype_l    383 383 3.69%   3.69%   ucrtbase.dll

Kerja bagus men-debug ini. Saya kira jalur kode lain yang memanggil isdigit juga akan diperlambat di windows.

Sekedar catatan untuk orang yang melihat xstrtod (dan terima kasih telah melakukannya BTW, ini sepertinya masalah yang sangat sulit): ada dua di antaranya (#19361). Dari atas kepala saya, saya tidak yakin mana yang digunakan dalam konteks apa.

Saya mungkin telah menemukan contoh python murni yang tampaknya menunjukkan perlambatan 2.5X yang serupa tetapi lebih kecil. Perhatikan juga variabilitasnya 15X lebih tinggi untuk kode 3.7.1. Mungkin menunjukkan bahwa argumen lokal diteruskan/digunakan dalam beberapa panggilan tetapi tidak yang lain.

Bisakah seseorang menguji ini di linux dan melihat apakah Anda melihat perbedaannya?

__Python 3.7.1__

digits = ''.join([str(i) for i in range(10)]*10000000)
%timeit digits.isdigit() # --> 2.5X slower on python 3.7.1
537 ms ± 14.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

__Python 3.5.2__

digits = ''.join([str(i) for i in range(10)]*10000000)
%timeit digits.isdigit() # --> 2.5X slower on python 3.7.1
215 ms ± 986 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)

-> Berdasarkan komentar dari: https://bugs.python.org/msg329789
tampaknya ini adalah tes Unicode murni. Jadi mungkin tidak ada hubungannya.

@cgohlke telah mengajukan contoh minimal yang bagus yang menunjukkan perlambatan: https://bugs.python.org/msg329790 Terima kasih! 👍

Terima kasih atas penyelidikannya @cgohlke - untuk 0,24 saya kira kita harus memasukkan ASCII isdigit
fungsi?

(MUSL, MIT berlisensi)
https://github.com/esmil/musl/blob/master/src/ctype/isdigit.c#L5

@ chris-b1 Saya memikirkan hal yang sama karena fungsinya yang cukup sederhana, namun mengubah lokal akan terbatas. Saya bertanya-tanya bagaimana fungsi windows isdigit akhirnya memanggil versi lokal. Saya tidak berpikir sumber itu tersedia.

Saya bertanya-tanya bagaimana fungsi windows isdigit akhirnya memanggil versi lokal. Saya tidak berpikir sumber itu tersedia.

Kode sumber untuk UCRT Windows tersedia dengan Windows SDK terbaru. Biasanya dipasang di bawah C:\Program Files (x86)\Windows Kits\10\Source .

Fungsi isdigit dan _isdigit_l didefinisikan dalam ucrt\convert\_ctype.cpp :

extern "C" extern __inline int (__cdecl isdigit)(int const c)
{
    return __acrt_locale_changed()
        ? (_isdigit_l)(c, nullptr)
        : fast_check(c, _DIGIT);
}

extern "C" extern __inline int (__cdecl _isdigit_l)(int const c, _locale_t const locale)
{
    _LocaleUpdate locale_update(locale);

    return _isdigit_l(c, locale_update.GetLocaleT());
}

Komentar berikut berasal dari fungsi _wsetlocale :

// If no call has been made to setlocale to change locale from "C" locale
// to some other locale, we keep locale_changed = 0. Other functions that
// depend on locale use this variable to optimize performance for C locale
// which is normally the case in applications.

Jadi jika saya memahaminya dengan benar. Bahkan jika kita menyetel lokal dengan Python ke “C”, fungsi windows isdigit akan tetap menggunakan pemanggilan lokal versi isdigit yang memperlambat penguraian karena lokal telah 'berubah'.

Apakah itu yang terjadi di python. 3.7.0a3? Menyetel lokal ke "C" memperlambat penguraian?

@jreback @TomAugspurger Apakah menurut Anda shim sederhana dari fungsi isdigit dalam kode parser C akan menjadi perbaikan yang dapat kami lakukan?

Ini akan mengasumsikan penyandian yang kompatibel dengan 'ASCII' untuk kolom numerik yang menurut saya harus mencakup semua/sebagian besar penyandian file csv untuk angka.

int isdigit(int c)
{
    return (unsigned)c-'0' < 10;
}

Ya, jika Anda ingin mengirimkan PR, ping saya, atau jika tidak, saya akan segera mendapatkannya

@chris-b1 Lakukanlah! 😄

@chris-b1 @jreback Terima kasih telah menyelesaikan ini! Sangat menghargai itu! 👍

Apakah halaman ini membantu?
0 / 5 - 0 peringkat