# Why does each BigFloat allocate a big String in addition to the MPFR big float object?

**URL:** https://discourse.julialang.org/t/why-does-each-bigfloat-allocate-a-big-string-in-addition-to-the-mpfr-big-float-object/92745
**Category:** Internals & Design
**Created:** [January 10, 2023, 7:18am UTC](https://discourse.julialang.org/t/why-does-each-bigfloat-allocate-a-big-string-in-addition-to-the-mpfr-big-float-object/92745 "2023-01-10T07:18:08Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)
#### Post date: [January 10, 2023, 7:18am UTC](https://discourse.julialang.org/t/why-does-each-bigfloat-allocate-a-big-string-in-addition-to-the-mpfr-big-float-object/92745/1 "2023-01-10T07:18:09Z")

</div>

I’m doing allocation profiling on some code that uses BigFloats at precision 2048, and I noticed that each time a BigFloat is allocated, half of the allocation seems to go to the MPFR object, and the other half to a String.

The relevant code in `base/mpfr.jl` calls this String a “gc handle”. I don’t know why this is necessary, but surely these String objects should take up much less than half space allocated for the Bigfloat?

The initial part of the `BigFloat` definition:

> <https://github.com/JuliaLang/julia/blob/master/base/mpfr.jl#L90-L108>

The `BigFloat` constructor that creates the String object:

> <https://github.com/JuliaLang/julia/blob/master/base/mpfr.jl#L110-L119>

---

<div class="post-metadata">

### Author: ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)
#### Post date: [January 10, 2023, 7:32am UTC](https://discourse.julialang.org/t/why-does-each-bigfloat-allocate-a-big-string-in-addition-to-the-mpfr-big-float-object/92745/2 "2023-01-10T07:32:59Z")

</div>

Now that I think about the code, I guess the intent behind it is for the String object to hold the memory of the MPFR object, so there shouldn’t be any additional allocation? So I guess this is a bug in the allocation profiler?

Here’s a screenshot of the Julia allocation profiler in the Code editor:

 ![bigfloat_alloc](https://global.discourse-cdn.com/julialang/original/3X/e/b/ebd110123a5349699cde118fad9e4901eb9e03ab.webp)

---

<div class="post-metadata">

### Author: ![thofma](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thofma/32/1691_2.png) [@thofma](https://discourse.julialang.org/u/thofma)
#### Post date: [January 10, 2023, 8:02am UTC](https://discourse.julialang.org/t/why-does-each-bigfloat-allocate-a-big-string-in-addition-to-the-mpfr-big-float-object/92745/3 "2023-01-10T08:02:39Z")

</div>

> [@nsajko](#):
>
> Now that I think about the code, I guess the intent behind it is for the String object to hold the memory of the MPFR object, so there shouldn’t be any additional allocation?

Yes, there is no additional allocation (your interpretation of the `String` object is correct).

Why do you think there is a Bug in the allocation profiler?

---

<div class="post-metadata">

### Author: ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)
#### Post date: [January 10, 2023, 8:16am UTC](https://discourse.julialang.org/t/why-does-each-bigfloat-allocate-a-big-string-in-addition-to-the-mpfr-big-float-object/92745/4 "2023-01-10T08:16:02Z")

</div>

> [@thofma](#):
>
> Why do you think there is a Bug in the allocation profiler?

Because two equal allocations are noted, both in the flamegraph and in the annotated source, instead of just one.

---

<div class="post-metadata">

### Author: ![thofma](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/thofma/32/1691_2.png) [@thofma](https://discourse.julialang.org/u/thofma)
#### Post date: [January 10, 2023, 8:37am UTC](https://discourse.julialang.org/t/why-does-each-bigfloat-allocate-a-big-string-in-addition-to-the-mpfr-big-float-object/92745/5 "2023-01-10T08:37:23Z")

</div>

The `BigFloat` object is allocated and the `String` is allocated. Why should there be one?

---

<div class="post-metadata">

### Author: ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)
#### Post date: [January 10, 2023, 8:58am UTC](https://discourse.julialang.org/t/why-does-each-bigfloat-allocate-a-big-string-in-addition-to-the-mpfr-big-float-object/92745/6 "2023-01-10T08:58:45Z")

</div>

_Before_ we exit the `BigFloat` constructor, there are already two allocations, as shown in both the flamegraph and the annotated source.

EDIT: I’m talking about this, specifically:

 ![alloc](https://global.discourse-cdn.com/julialang/original/3X/b/8/b80aef4af850381342b038c154741133fac7a63f.webp)

_Within_ the constructor, there are two equal allocations shown, and then the total is their sum. I guess this causes the profiler to double-count the BigFloat size?

---

<div class="post-metadata">

### Author: ![skleinbo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/skleinbo/32/36080_2.png) [@skleinbo](https://discourse.julialang.org/u/skleinbo)
#### Post date: [January 10, 2023, 9:46am UTC](https://discourse.julialang.org/t/why-does-each-bigfloat-allocate-a-big-string-in-addition-to-the-mpfr-big-float-object/92745/7 "2023-01-10T09:46:49Z")

</div>

> [@nsajko](#):
>
> _Before_ we exit the `BigFloat` constructor, there are already two allocations

Yes, because the `BigFloat` object is instantiated/allocated in the call to `_BigFloat`.

If you look at the allocation profile, you will find there are two kinds of allocations; the string and the `BigFloat` (although the profiler can’t figure out the type here and calls it `UnknownType`). As you can see, they are of different size. Play with `precision` and observe the string allocation change size. It isn’t doubly allocated though.

```julia-auto
Profile.Allocs.@profile for i in 1:10000000 BigFloat(;precision=2048) end
result = Profile.Allocs.fetch()
result = sort(result.allocs, by=x->x.size)
result[[begin,end]]

2-element Vector{Profile.Allocs.Alloc}:
 Profile.Allocs.Alloc(Profile.Allocs.UnknownType, Base.StackTraces.StackFrame[ijl_gc_pool_alloc at libjulia-internal.1.8.dylib:?, ...], 48)
 Profile.Allocs.Alloc(String, Base.StackTraces.StackFrame[ijl_alloc_string at libjulia-internal.1.8.dylib:?, ...], 256)

```

---

<div class="post-metadata">

### Author: ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)
#### Post date: [January 10, 2023, 9:57am UTC](https://discourse.julialang.org/t/why-does-each-bigfloat-allocate-a-big-string-in-addition-to-the-mpfr-big-float-object/92745/8 "2023-01-10T09:57:25Z")

</div>

Ah, I thought the profiler was reporting allocation size, but I guess it’s only considering the number of allocations. The Code editor Julia plugin, I mean.
