-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
2x performance regression when comparing types #11425
Comments
AFAICT @ScottPJones's version is different from yours as it gets specialized on function check_string{T<:Union(Vector{UInt16},Vector{UInt32},Vector{Char},AbstractString)}(str::T, pos::Int, len::Int, options::Integer=0) |
But if you profile @ScottPJones function you will see the profiler takes large hits on all lines where the type comparison occurs. |
And if you execute his bench on commit 8fc5b4e there are no significant regression compared to 0.3.8 |
Sure, I'm not saying it doesn't exist -- just that your example might be a bit different from his. |
If the method gets specialized on
The performance difference gets even worse.
for 195bd01:
|
Ah, I told you it was different! :-p
On 0.4 master @code_native test_regression(10000000, [1.])
.text
Filename: none
Source line: 3
pushq %rbp
movq %rsp, %rbp
pushq %r14
pushq %rbx
movq %rdi, %rbx
testq %rbx, %rbx
jle L61
Source line: 3
movabsq $"==", %r14
L29: movabsq $139878791540752, %rdi # imm = 0x7F3811AE7010
movabsq $139878791788240, %rsi # imm = 0x7F3811B236D0
callq *%r14
decq %rbx
jne L29
L61: popq %rbx
popq %r14
popq %rbp
ret On 0.3.8: @code_native test_regression(10000000, [1.])
.text
Filename: none
Source line: 0
push rbp
mov rbp, rsp
push r14
push rbx
mov rbx, rdi
Source line: 2
test rbx, rbx
jle 35
Source line: 3
movabs r14, 140453940809840
nop dword ptr [rax]
mov edi, 23434032
mov esi, 37650384
call r14
dec rbx
jne -18
pop rbx
pop r14
pop rbp
ret |
Fixed pretty handily by the following stylish patch: diff --git a/base/operators.jl b/base/operators.jl
index fc3e8ef..edb218f 100644
--- a/base/operators.jl
+++ b/base/operators.jl
@@ -19,7 +19,8 @@ isless(x::FloatingPoint, y::FloatingPoint) = (!isnan(x) & isna
isless(x::Real, y::FloatingPoint) = (!isnan(x) & isnan(y)) | (signbit(
isless(x::FloatingPoint, y::Real ) = (!isnan(x) & isnan(y)) | (signbit(
-==(T::Type, S::Type) = typeseq(T, S)
+=={T}(::Type{T}, ::Type{T}) = true
+==(T::Type, S::Type) = false
|
My theory about why this regression happened is that #10380 removed the extra definition |
The fix in 66fb53a has some strange side effects. Consider the code here (the reason for this code will be a different issue): https://gist.github.com/Jutho/373f2c65ec129790426e The three if's on line 39, 42 and 48 should not happen, except maybe when |
Could you extract an example of two types where |
Maybe this? julia> dict = Dict{DataType, Vector{Any}}()
dDict{DataType,Array{Any,1}} with 0 entries
julia> dict[Tuple{TypeVar(:T, Signed, true), Base.GMP.BigInt}] = [1]
1-element Array{Int64,1}:
1
julia> dict
Dict{DataType,Array{Any,1}} with 1 entry:
Tuple{T<:Signed,Base.GMP… => Any[1]
julia> dict[Tuple{Int64, Rational}]
1-element Array{Any,1}:
1 |
Or even shorter julia> Tuple{Int64, Rational} == Tuple{TypeVar(:T, Signed, true), Base.GMP.BigInt}
true
julia> @which Tuple{Int64, Rational} == Tuple{TypeVar(:T, Signed, true), Base.GMP.BigInt}
ERROR: no unique matching method for the specified argument types |
Ok, that's pretty weird. But you are really not supposed to construct TypeVars directly. |
I agree. In his case, the (bounded) |
So the problem is only with the bound |
Well, changing them to unbound changes the meaning of the function signatures.... |
I'd like to try to fix this properly, since == is clearly doing something wrong. However we must keep priorities in mind. |
There is certainly more at play and is not restricted to issues with a = Tuple{Int32,Unsigned}
b = Tuple{Rational,Rational}
a == b # => false However, at a fresh Julia REPL, copy pasting the code function analyzeconvert()
# copy from https://gist.github.com/Jutho/373f2c65ec129790426e
end
types,table,dict = analyzeconvert()
a = Tuple{Int32,Unsigned}
b = Tuple{Rational,Rational}
a == b # => true |
I think it is just a combination of the issue compareing bound |
As shown in my comment above #11425 (comment), the dispatch system is obviously confused and the method table is probably not in a better situation. I agree with @JeffBezanson though that this by itself is not of high priority (unless it is causing other issues...) |
Ok thanks, I have been bitten by not recognizing #265 before. |
Actually it might be slightly different since #265 is more about directly linking the function and this one is probably about bad specialization in the method cache..... |
Another thing I noticed, changed by the fix here: compare the timing of |
Between 8fc5b4e and 195bd01 a 2x performance regression happened on this test case:
Output from 195bd01:
Output from 8fc5b4e:
The test case are a reduction from this bench test: https://gist.github.com/ScottPJones/f3fb082ac30d337d91bc, discussed in #11004 and https://groups.google.com/forum/m/?fromgroups#!topic/julia-dev/eI3x5Een1uI.
I think this is the single reason for the regression observed by @ScottPJones.
The text was updated successfully, but these errors were encountered: