# ANN: JJ.jl -- library for J-like verb rank in Julia

**URL:** <https://discourse.julialang.org/t/ann-jj-jl-library-for-j-like-verb-rank-in-julia/83361>\
**Category:** Package Announcements\
**Created:** [June 26, 2022, 2:17pm UTC](https://discourse.julialang.org/t/ann-jj-jl-library-for-j-like-verb-rank-in-julia/83361 "2022-06-26T14:17:17Z")\
**Posts on this page:** 1\
**Showing post:** 9

<div class="post-metadata">

**Author:** ![mcabbott](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mcabbott/32/6603_2.png) [@mcabbott](https://discourse.julialang.org/u/mcabbott)\
**Post date:** [June 27, 2022, 10:21pm UTC](https://discourse.julialang.org/t/ann-jj-jl-library-for-j-like-verb-rank-in-julia/83361/9 "2022-06-27T22:21:35Z")

</div>

One reason that some combined operations are their own functions is that these can be more efficient than making slices. You can see this with your `batched_mul` example, where the fused on saves allocations, and (IIRC) will also parallelise better on larger cases, and call special CUDA routines.

```julia
julia> using NNlib, BenchmarkTools

julia> C = @btime $A ⊠ $B; # special batched matrix multiplication
  309.363 ns (1 allocation: 400 bytes) # fused, 1 allocation of final Array

julia> using JJ

julia> C ≈ @btime rank"2 * 2"($A, $B) # just rank the standard one!
  803.831 ns (7 allocations: 768 bytes) # allocates slices, returns lazy JuliennedArrays.Align
true

```

Or a simpler example:

```julia
julia> M = transpose(rand(10^3, 10^3));

julia> V = @btime vec(sum($M, dims=1));
  158.417 μs (3 allocations: 8.02 KiB)

julia> V ≈ @btime rank"sum 1"($M) # this is less cache-friendly than sum
  908.500 μs (1 allocation: 7.94 KiB)
true

```

You might like this earlier [vmap discussion](https://discourse.julialang.org/t/julias-broadcast-vs-jaxs-vmap/38990) about trying to make such transformations automatically.

Such concerns aside, some other ways to handle slices besides SplitApplyCombine & JuliennedArrays (mentioned above) include these. They are certainly more verbose than `rank`:

```julia
julia> C ≈ @btime stack(*, eachslice($A, dims=3), eachslice($B, dims=3)) # should work with PR43334
  872.121 ns (14 allocations: 1.27 KiB) # allocates slices, returns Array
true

julia> using TensorCast # (my package)

julia> C ≈ @cast C2[i,j,n] := (A[:,:,n] * B[:,:,n])[i,j]
true

```

---

_[View the full topic](https://discourse.julialang.org/t/ann-jj-jl-library-for-j-like-verb-rank-in-julia/83361)._
