Skip to content

defining a few constructor methods gives 2x import slowdown #27599

@stevengj

Description

@stevengj

In updating PyCall for the latest Julia (JuliaPy/PyCall.jl#505), I noticed that dealing with #23273 led to a huge slowdown.

In particular, PyCall used to define only convert(T, o::PyObject) methods for converting Python objects to native Julia types, and I got T(o) constructors automatically. In updating, I first tried changing all of my convert methods to constructors, but this led to 30x (!) load-time slowdowns (after precompiling) on 0.6, and out-of-memory errors in Travis. Instead, I opted to leave the convert methods as-is.

What I noticed is that, if I also add an explicit constructor that calls the convert method, to preserve the constructor API on 0.7, it led to a big slowdown in load time. In particular, just adding

if VERSION >= v"0.7.0-DEV.3152" # julia#23273
    (::Type{T})(po::PyObject) where
        {T<:Union{Number,Nothing,AbstractString,Symbol,Array,Ptr{Cvoid},
        Function,Tuple,Pair,Dict,AbstractRange,Dates.AbstractTime}} =
        convert(T, po)
end

(at the end of PyCall/src/conversions.jl in my JuliaPy/PyCall.jl#505 branch) caused the using PyCall time (after precompiling) to slow down from 10s to 20s on my machine. (And it is 3.5s on 0.6, so there are other slowdowns too.)

It is a little disturbing that adding 4 lines to a file can slow down loading by 10 seconds, so I thought someone might want to look into this. (I'm guessing that there is some performance gotcha associated with defining new constructors for very common types like Number.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions