-
Notifications
You must be signed in to change notification settings - Fork 97
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
Hint on the number of tags in tagmap in Julia #387
Conversation
Hmm, I don't like you're hard coding UInt32 so many times, why not just keep T? |
Also, sizehint on dictionary doesn't work the way you want it to |
I think that having T when it always fixed to be UInt32 is not useful, it is like using |
I used |
Also (this is incredible, bug??) if I use T=UInt32 in the concurrent version: Concurrent version with T=UInt32module RelatedCon
using JSON3, Dates, StaticArrays, ChunkSplitters
using Base.Threads: @threads, nthreads
export main
const topn = 5
struct PostData
_id::String
title::String
tags::Vector{String}
end
struct RelatedPost
_id::String
tags::Vector{String}
related::SVector{topn, PostData}
end
function fastmaxindex!(xs::Vector{T}, topn, maxn, maxv) where {T}
maxn .= one(T)
maxv .= zero(T)
top = maxv[1]
for (i, x) in enumerate(xs)
if x > top
maxn[1], maxv[1] = i, x
for j in 2:topn
if maxv[j-1] > maxv[j]
maxv[j-1], maxv[j] = maxv[j], maxv[j-1]
maxn[j-1], maxn[j] = maxn[j], maxn[j-1]
end
end
top = maxv[1]
end
end
reverse!(maxn)
return
end
function related(posts)
T = UInt32
# key is every possible "tag" used in all posts
# value is indicies of all "post"s that used this tag
tagmap = Dict{String,Vector{T}}()
for (idx, post) in enumerate(posts)
for tag in post.tags
tags = get!(() -> T[], tagmap, tag)
push!(tags, idx)
end
end
relatedposts = Vector{RelatedPost}(undef, length(posts))
@threads for (postsrange, _) in chunks(posts, nthreads())
topn = 5
maxn = MVector{topn,T}(undef)
maxv = MVector{topn,T}(undef)
taggedpostcount = Vector{T}(undef, length(posts))
for i in postsrange
post = posts[i]
taggedpostcount .= zero(T)
# for each post (`i`-th)
# and every tag used in the `i`-th post
# give all related post +1 in `taggedpostcount` shadow vector
for tag in post.tags
for idx in tagmap[tag]
taggedpostcount[idx] += one(T)
end
end
# don't self count
taggedpostcount[i] = zero(T)
fastmaxindex!(taggedpostcount, topn, maxn, maxv)
relatedpost = RelatedPost(post._id, post.tags, SVector{topn}(@view posts[maxn]))
relatedposts[i] = relatedpost
end
end
return relatedposts
end
function main()
json_string = read(@__DIR__()*"/../../../posts.json", String)
posts = JSON3.read(json_string, Vector{PostData})
fake_posts = fill(posts[1], length(posts))
related(fake_posts) #warmup
start = now()
all_related_posts = related(posts)
println("Processing time (w/o IO): $(now() - start)")
open(@__DIR__()*"/../../../related_posts_julia_con.json", "w") do f
JSON3.write(f, all_related_posts)
end
end
end # module RelatedCon Julia becomes 200x slower D: |
If we use T at least you don't have to change 10 different code when we need to change |
yes, indeed this is a good reason to keep it, will restore it then, but how that concurrent version is so slow? Does it happen also on your computer? |
idk, I'm gonna maybe get a Azure VM tmr... |
But could you please confirm me though that you see that slowdown on your machine? Seems something to create a MWE to report My specs: julia> versioninfo()
Julia Version 1.9.3
Commit bed2cd540a1 (2023-08-24 14:43 UTC)
Build Info:
Official https://julialang.org/ release
Platform Info:
OS: Linux (x86_64-linux-gnu)
CPU: 12 × AMD Ryzen 5 5600H with Radeon Graphics
WORD_SIZE: 64
LIBM: libopenlibm
LLVM: libLLVM-14.0.6 (ORCJIT, znver3)
Threads: 12 on 12 virtual cores |
This would probably be helpful, I have to say that I see a lot of variance on my computer as well, e.g. from the last @jinyus benchmark at #386 (comment)
|
But I see the same oscillations on my computer as well though, and interestingly the oscillation happen much more between different Julia sessions (e.g. if I restart Julia and then repeat the benchmark I can get somewhat different results) |
Now it adds only -O3 + sizehint! which should be okay |
anyway that problem with |
this is known |
Let me know if you think it is worth to see this merged @Moelf |
I'm neutral, I kinda want to remove |
the hint seems good to me to keep so I think it is ready to be merged @jinyus |
(I removed -O3 also in Related.jl) |
main: This PR:
|
for me without |
@jinyus maybe it's time to consider use In particular, when running on vCPU, we're very likely to get unlucky big time, but we will never be too lucky since the program is deterministic, so |
I have to say @Moelf that I disagree, this seems like only a problem with Julia and to a much lesser extent NodeJS, look at the raw results of the last run https://github.com/jinyus/related_post_gen/pull/393/files#diff-2a2b2d627a2e6ead1faf8f7a575d8662c2dfbc73505e094767591470c213c01b, Julia performed badly since its results varied so much. The only other language with this kind of pattern is NodeJS, but the oscillations are less large. The cause of this is unclear to me. The only thing I can think of is that starting the processes again and again in Julia takes time, while in other languages doesn't, so between one run and the other there is a bigger delay. But still I don't really get the implications of such a reasoning actually. |
can we merge this since seems like |
I would try too, but @jinyus showed the same strange timings patterns also for this pr. Let's try though |
Also removed the T, being a bit more explicit.
(the rules state that there are max 100 tags)
@Moelf