Skip to content

MWE: Performance of views #222

@MikaelSlevinsky

Description

@MikaelSlevinsky

I'd really like to start using this library seriously, but certain elements (at least of my understanding) leave me perplexed. I can write two simple mul!-like functions that are faster than the built-in mul! for a diagonal matrix, but 1) simply recreating the blocks is fastest but should be unnecessary and 2) views, which do not recreate the banded-block-banded matrix, are slower and allocate. Here's the example:

EDIT: ok, the fastest way is to view the data blocks of the banded-block-banded matrix

julia> using BlockBandedMatrices

julia> function my_special_mul!(y, D, x)
           @assert size(D, 1) == size(D, 2) == length(x) == length(y)
           n = blocklength(x)
           for j in 1:n
               xb = x[Block(j)]
               DB = D[Block(j, j)]
               for i in 1:length(xb)
                   y.blocks[j][i] = DB[i, i]*xb[i]
               end
           end
           return y
       end
my_special_mul! (generic function with 1 method)

julia> function my_special_mul_with_a_view!(y, D, x)
           @assert size(D, 1) == size(D, 2) == length(x) == length(y)
           n = blocklength(x)
           for j in 1:n
               xb = x.blocks[j]
               DB = view(D, Block(j, j))
               for i in 1:length(xb)
                   y.blocks[j][i] = DB[i, i]*xb[i]
               end
           end
           return y
       end
my_special_mul_with_a_view! (generic function with 1 method)

julia> function my_special_mul_through_data!(y, D, x)
           @assert size(D, 1) == size(D, 2) == length(x) == length(y)
           n = blocklength(x)
           @inbounds for j in 1:n
               xb = view(x, Block(j))
               DB = view(D.data, Block(j))
               yb = view(y, Block(j))
               for i in 1:length(xb)
                   yb[i] = DB[i]*xb[i]
               end
           end
           return y
       end
my_special_mul_through_data! (generic function with 1 method)

julia> for n in 20:20:200
           D = BandedBlockBandedMatrix{Float64}(I, 1:n, 1:n, (0, 0), (0, 0))
           x = BlockVector(randn(sum(1:n)), 1:n)
           y = zero(x)
           @time my_special_mul_through_data!(y, D, x);
           @time my_special_mul!(y, D, x);
           @time my_special_mul_with_a_view!(y, D, x);
           @time mul!(y, D, x);
       end
  0.056795 seconds (38.60 k allocations: 2.499 MiB, 99.94% compilation time)
  0.032453 seconds (16.87 k allocations: 1.132 MiB, 99.91% compilation time)
  0.039557 seconds (39.35 k allocations: 2.721 MiB, 99.92% compilation time)
  0.000117 seconds (22 allocations: 1.344 KiB)
  0.000008 seconds
  0.000018 seconds (80 allocations: 17.656 KiB)
  0.000028 seconds (820 allocations: 51.250 KiB)
  0.000195 seconds (42 allocations: 2.594 KiB)
  0.000010 seconds
  0.000029 seconds (120 allocations: 36.375 KiB)
  0.000061 seconds (1.83 k allocations: 114.375 KiB)
  0.000403 seconds (62 allocations: 3.844 KiB)
  0.000015 seconds
  0.000041 seconds (160 allocations: 61.438 KiB)
  0.000093 seconds (3.24 k allocations: 202.500 KiB)
  0.000736 seconds (82 allocations: 5.094 KiB)
  0.000025 seconds
  0.000124 seconds (200 allocations: 93.312 KiB)
  0.000211 seconds (5.05 k allocations: 315.625 KiB)
  0.000701 seconds (102 allocations: 6.344 KiB)
  0.000031 seconds
  0.000078 seconds (240 allocations: 131.750 KiB)
  0.000186 seconds (7.26 k allocations: 453.750 KiB)
  0.000683 seconds (122 allocations: 7.594 KiB)
  0.000041 seconds
  0.000113 seconds (280 allocations: 176.125 KiB)
  0.000239 seconds (9.87 k allocations: 616.875 KiB)
  0.000671 seconds (142 allocations: 8.844 KiB)
  0.000052 seconds
  0.000126 seconds (320 allocations: 227.281 KiB)
  0.000312 seconds (12.88 k allocations: 805.000 KiB)
  0.000514 seconds (162 allocations: 10.094 KiB)
  0.000066 seconds
  0.000158 seconds (360 allocations: 284.938 KiB)
  0.000383 seconds (16.29 k allocations: 1018.125 KiB)
  0.001663 seconds (182 allocations: 11.344 KiB)
  0.000081 seconds
  0.000180 seconds (400 allocations: 349.719 KiB)
  0.000613 seconds (20.10 k allocations: 1.227 MiB)
  0.001204 seconds (202 allocations: 12.594 KiB)

julia> 

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions