فرض کنید یک لیست 100 میلیون عنصری که تمامشان از جنس float هستند داریم، میخواهیم این لیست را به یک آرایه numpy تبدیل کنیم. راه مرسوم این کار استفاده از تابع array یا توابع دیگری که روی این تابع سوار شدهاند است:
از ورژنهای اخیر numpy، نوع پیشفرض برای ساخت آرایه دارای اعداد اعشاری، np.float64 است، در نتیجه dtype آرایه نهایی np.float64 میشود.
حالا ممکنه بپرسید مشکل کار کجاست؟
کارکرد numpy به این صورت است که بعد از خواندن اولین عنصر لیست متوجه میشود باید نوع آرایه خروجی np.float64 باشد پس از عنصر دوم به بعد سعی میکند تمام عناصر را به np.float64 تبدیل کند. همه چی به نظر خوب میاد بهجز اینکه به یه مرحله اشاره نکردیم. قبل از اینکه numpy کار تبدیل را انجام دهد ابتدا چک میکند که میتواند عنصر جدید را np.float64 تبدیل کند یا نه، که همین یک سربار اضافی را به ما تحمیل میکند، ما از نوع عناصر لیست مطمئن هستیم پس نیاز نیست numpy این کار را انجام دهد.
برای حذف مرحله اضافی ذکر شده کافیه هنگام تبدیل dtype مد نظرمون رو بصورت صریح بگیم. اینجوری دیگه numpy اون مرحله چک اضافه رو انجام نمیده و فقط سعی میکنه اعداد رو به np.float64 تبدیل کنه و اگر نتونست این کار رو بکنه اون موقع یک exception پرتاب میکنه.
روی ماشین شخصی من که پردازنده i7-6700K داره کد دوم بصورت میانگین حداقل یک ثانیه زودتر اجرا میشه روی ماشین ضعیفتر به ده ثانیه هم میرسه. اما بصورت کلی در ابعاد و سایز بزرگتر حتی ماشینهای قویتر رو هم اذیت میکنه.
اگر از نظر شما چیزی اشتباه یا ناقص است لطفا در نظرات بفرمایید.
Reference: https://github.com/numpy/numpy/issues/21259