# Const FileData = AbstractVector{UInt8}

**URL:** <https://discourse.julialang.org/t/const-filedata-abstractvector-uint8/50147>\
**Category:** Performance\
**Created:** [November 14, 2020, 3:06pm UTC](https://discourse.julialang.org/t/const-filedata-abstractvector-uint8/50147 "2020-11-14T15:06:58Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![JuergenD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juergend/32/18970_2.png) [@JuergenD](https://discourse.julialang.org/u/JuergenD)\
**Post date:** [November 14, 2020, 3:06pm UTC](https://discourse.julialang.org/t/const-filedata-abstractvector-uint8/50147/1 "2020-11-14T15:06:58Z")

</div>

Hi,

I thought `const FileData = AbstractVector{UInt8}` it is just an alias, but afaik it is not.

```
buf = obj.buf # buf is defined as ::FileData
while start < size
    ...
    fn(@view buf[start:stop])
    ...
end

```

The version above allocates memory in every `@view` invocation. In my case, it is several GBs of data.  
The version below, allocates (almost) nothing. I expected this also with the version above. Any explanation why that is not the case?

```
buf::Vector{UInt8} = obj.buf # buf is defined as FileData
while start < size
   ...
   fn(@view buf[start:stop])
   ...
end

```

thanks, Juergen

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [November 14, 2020, 3:52pm UTC](https://discourse.julialang.org/t/const-filedata-abstractvector-uint8/50147/2 "2020-11-14T15:52:21Z")

</div>

`AbstractVector{UInt8}` and `Vector{UInt8}` are two very different things, why did you not compare using `const FileData = Vector{UInt8}` instead of `const FileData = AbstractVector{UInt8}`?

---

<div class="post-metadata">

**Author:** ![JuergenD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juergend/32/18970_2.png) [@JuergenD](https://discourse.julialang.org/u/JuergenD)\
**Post date:** [November 14, 2020, 4:14pm UTC](https://discourse.julialang.org/t/const-filedata-abstractvector-uint8/50147/3 "2020-11-14T16:14:16Z")

</div>

Now I **completely** removed `const FileData = AbstractVector{UInt8}` from the source code.

This is still slow

```julia
buf = obj.buf # buf is defined as FileData
while start < size
   ...
   fn(@view buf[start:stop])
   ...
end

```

This is 30x times faster (and has almost no allocations):

```julia
buf::Vector{UInt8} = obj.buf # buf is defined as FileData
while start < size
   ...
   fn(@view buf[start:stop])
   ...
end

```

---

<div class="post-metadata">

**Author:** ![johnmyleswhite](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/johnmyleswhite/32/31_2.png) [@johnmyleswhite](https://discourse.julialang.org/u/johnmyleswhite)\
**Post date:** [November 14, 2020, 4:33pm UTC](https://discourse.julialang.org/t/const-filedata-abstractvector-uint8/50147/4 "2020-11-14T16:33:02Z")

</div>

Did you replace `const FileData = AbstractVector{UInt8}` with `const FileData = Vector{UInt8}`? That was the suggestion @Henrique_Becker made. You seem to be doing something different.

---

<div class="post-metadata">

**Author:** ![Skoffer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skoffer/32/378_2.png) [@Skoffer](https://discourse.julialang.org/u/Skoffer)\
**Post date:** [November 14, 2020, 4:56pm UTC](https://discourse.julialang.org/t/const-filedata-abstractvector-uint8/50147/5 "2020-11-14T16:56:19Z")

</div>

Try wrapping your calculation in a function. You are working in a global scope and it is not a very good idea for performance.

---

<div class="post-metadata">

**Author:** ![JuergenD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juergend/32/18970_2.png) [@JuergenD](https://discourse.julialang.org/u/JuergenD)\
**Post date:** [November 15, 2020, 10:55am UTC](https://discourse.julialang.org/t/const-filedata-abstractvector-uint8/50147/6 "2020-11-15T10:55:37Z")

</div>

@Skoffer: this is just a code snippet, actually taken from a function

@johnmyleswhite / @Henrique_Becker I now reverted the latest changes and only changed `const FileData = AbstractVector{UInt8}` with `const FileData = Vector{UInt8}`. I had to make some changes to our test code, which is using b"…" a lot, which creates CodeUnits{UInt8,String}. That was my original reason to use AbstractVector. With this change the code now runs much faster and much fewer allocations.

And even though I understand the performance increase, I still don’t understand the reason why Julia needs to do so many allocations (copies I assume) when passing abstract types around. I thought variables and function arguments are just binding to the same “slot”, no matter whether abstract or not. At least as long as I’m not converting to another concrete type.

-Juergen

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [November 15, 2020, 3:54pm UTC](https://discourse.julialang.org/t/const-filedata-abstractvector-uint8/50147/7 "2020-11-15T15:54:00Z")

</div>

> [@JuergenD](#):
>
> why Julia needs to do so many allocations (copies I assume) when passing abstract types around.

Hmmm, I am not sure this has anything with copies. Often the allocations come from the fact the type cannot be _unboxed_ this is, just stored as it is, it is instead behind a pointer which also stores the current concrete type saved in the same field (this indirection layer needs to be separately allocated many times). Also, if you had an struct that is concrete, but had a _boxed_/abstract field inside, any function receiving a struct will specialize for this concrete struct, but when it has to deal with the inner field then it has to work around any possible type that may be there what is know to generate allocation. One way to avoid that is not manipulating the _boxed_ field directly in the function that takes your struct, but instead grouping all computation over that field inside a function and just passing the field to it, so this inner function will be specialized to the right type. This technique is called “function barrier” and described in the docs.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [November 16, 2020, 7:47am UTC](https://discourse.julialang.org/t/const-filedata-abstractvector-uint8/50147/8 "2020-11-16T07:47:43Z")

</div>

> [@JuergenD](#):
>
> this is just a code snippet, actually taken from a function

Note that it would be much easier to help with a self-contained MWE.

> [@Please read: make it easier to help you](https://discourse.julialang.org/t/psa-make-it-easier-to-help-you/14757/):
>
> Welcome to the Julia Discourse! We are enthusiastic about helping Julia programmers, both beginner and experienced. This public service announcement (PSA) outlines best practices when asking for help. Following these points makes it easier for us to help you and more likely you’ll get a prompt, useful answer. Keywords are highlighted to make it easier to refer to specific points. Choose a descriptive title that captures the key part of your question, eg “plots with multiple axes” instead of …
