-
Notifications
You must be signed in to change notification settings - Fork 157
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
Refactor degree
& coeff
for Add
& Mul
#685
Conversation
Codecov Report
@@ Coverage Diff @@
## master #685 +/- ##
==========================================
+ Coverage 76.49% 76.52% +0.02%
==========================================
Files 23 23
Lines 2719 2722 +3
==========================================
+ Hits 2080 2083 +3
Misses 639 639
📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
Have you checked that this is effectively more efficient ? using BenchmarkTools, LinearAlgebra
import SymbolicUtils: Mul
using Symbolics
main() = begin
@variables x
e = (2x + 1) * (3x - 1) * (4x^2 - 1) |> expand
# old implementation
@eval Symbolics degree(p::Mul, sym=nothing) = sum(degree(k^v, sym) for (k, v) in zip(keys(p.dict), values(p.dict)))
@btime degree($e)
# your proposed alternative
@eval Symbolics degree(p::Mul, sym=nothing) = dot(degree.(keys(p.dict), sym), values(p.dict))
@btime degree($e)
# from https://github.com/JuliaSymbolics/Symbolics.jl/pull/677
@eval Symbolics degree(p::Mul, sym=nothing) = sum(degree(k^v, sym) for (k, v) in p.dict)
@btime degree($e)
return
end
main()
#=
3.432 μs (20 allocations: 760 bytes) # old
8.569 μs (60 allocations: 2.40 KiB) # your implementation
3.403 μs (16 allocations: 632 bytes) # https://github.com/JuliaSymbolics/Symbolics.jl/pull/677
Julia Version 1.7.3
Commit 742b9abb4d* (2022-05-06 12:58 UTC)
Platform Info:
OS: Linux (x86_64-linux-gnu)
CPU: Intel(R) Xeon(R) CPU E5-2670 0 @ 2.60GHz
WORD_SIZE: 64
LIBM: libm
LLVM: libLLVM-12.0.1 (ORCJIT, sandybridge)
=# |
Oh I see. Broadcast is unnecessary. Thanks for doing the benchmark! |
Could you try the updated one? degree(p::Mul, sym=nothing) = sum(degree(k, sym) * v for (k, v) in p.dict) with this input @variables xs[1:10000]
e = prod(x^i for (i, x) in enumerate(xs)) The following measurement using BenchmarkTools
import SymbolicUtils: Mul
using Symbolics
main() = begin
@variables xs[1:10000]
e = prod(x^i for (i, x) in enumerate(xs))
# old implementation
@eval Symbolics degree(p::Mul, sym=nothing) = sum(degree(k^v, sym) for (k, v) in zip(keys(p.dict), values(p.dict)))
@btime degree($e)
# old proposition with broadcast
@eval Symbolics degree(p::Mul, sym=nothing) = dot(degree.(keys(p.dict), sym), values(p.dict))
@btime degree($e)
# from https://github.com/JuliaSymbolics/Symbolics.jl/pull/677
@eval Symbolics degree(p::Mul, sym=nothing) = sum(degree(k^v, sym) for (k, v) in p.dict)
@btime degree($e)
# updated
@eval Symbolics degree(p::Mul, sym=nothing) = sum(degree(k, sym) * v for (k, v) in p.dict)
@btime degree($e)
return
end
main() gives
|
Indeed, this is now even better:
When updating something for performance, you should never assume, and always benchmark for real concrete improvements. |
You're right. Thank you! |
degree(::Mul)
degree
& coeff
for Add
& Mul
Mul
andAdd