# Very slow loading speed of TIFF images

**URL:** https://discourse.julialang.org/t/very-slow-loading-speed-of-tiff-images/99826
**Category:** New to Julia
**Created:** [June 4, 2023, 2:07am UTC](https://discourse.julialang.org/t/very-slow-loading-speed-of-tiff-images/99826 "2023-06-04T02:07:51Z")
**Posts on this page:** 16
**Page:** 1

<div class="post-metadata">

### Author: ![Kadii](https://avatars.discourse-cdn.com/v4/letter/k/9fc29f/32.png) [@Kadii](https://discourse.julialang.org/u/Kadii)
#### Post date: [June 4, 2023, 2:07am UTC](https://discourse.julialang.org/t/very-slow-loading-speed-of-tiff-images/99826/1 "2023-06-04T02:07:51Z")

</div>

I’m very new to Julia. I’m trying to replace my Matlab code with Julia. I compared TIFF image loading speeds in Matlab and Julia, but the Matlab’s `imread()` is way faster than the Images’ `load()`. Is there any way to speed up the TIFF image loading?

The followings are codes I used. The test image was a 565 x 552 RGB image (~2MB).

**Matlab**

```julia
fname = "test_image.tiff";
tic;
for n = 1:5
    img = double(imread(fname));
end
toc;

> Elapsed time is 0.149297 seconds.
> Elapsed time is 0.039244 seconds.
> Elapsed time is 0.040094 seconds.

```

**Julia**

```julia
using Images
fname = "test_image.tiff"
juliaRead() = begin
	for n ∈ 1:5
		load(fname)
	end
end
@time juliaRead()

> 3.442524 seconds (1.83 M allocations: 137.901 MiB, 37.48% gc time, 33.34% compilation time: 55% of which was recompilation)
> 1.193470 seconds (2.29 k allocations: 20.828 MiB, 98.60% gc time)
> 1.196542 seconds (2.29 k allocations: 20.828 MiB, 98.45% gc time)

```

---

<div class="post-metadata">

### Author: ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)
#### Post date: [June 4, 2023, 4:23am UTC](https://discourse.julialang.org/t/very-slow-loading-speed-of-tiff-images/99826/2 "2023-06-04T04:23:21Z")

</div>

Whay package are you using to read tiff images?

> **[GitHub - tlnagy/TiffImages.jl: 💎 Pure-Julia TIFF I/O with a focus on...](https://github.com/tlnagy/TiffImages.jl)**
>
> 💎 Pure-Julia TIFF I/O with a focus on correctness 🧐 - GitHub - tlnagy/TiffImages.jl: 💎 Pure-Julia TIFF I/O with a focus on correctness 🧐

> **[GitHub - JuliaIO/ImageIO.jl: Load images in Julia. Designed for FileIO...](https://github.com/JuliaIO/ImageIO.jl)**
>
> Load images in Julia. Designed for FileIO interaction. Supports PNG and Portable Bitmap formats - GitHub - JuliaIO/ImageIO.jl: Load images in Julia. Designed for FileIO interaction. Supports PNG an...

> **[GitHub - tlnagy/OMETIFF.jl: I/O operations for OME-TIFF files in Julia](https://github.com/tlnagy/OMETIFF.jl)**
>
> I/O operations for OME-TIFF files in Julia. Contribute to tlnagy/OMETIFF.jl development by creating an account on GitHub.

---

<div class="post-metadata">

### Author: ![Kadii](https://avatars.discourse-cdn.com/v4/letter/k/9fc29f/32.png) [@Kadii](https://discourse.julialang.org/u/Kadii)
#### Post date: [June 4, 2023, 4:43am UTC](https://discourse.julialang.org/t/very-slow-loading-speed-of-tiff-images/99826/3 "2023-06-04T04:43:07Z")

</div>

mkitti,

I tried the Images package which I believed it was using the TiffImages function.

---

<div class="post-metadata">

### Author: ![joa-quim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/joa-quim/32/227_2.png) [@joa-quim](https://discourse.julialang.org/u/joa-quim)
#### Post date: [June 4, 2023, 7:57am UTC](https://discourse.julialang.org/t/very-slow-loading-speed-of-tiff-images/99826/4 "2023-06-04T07:57:33Z")

</div>

With GMT (a 601x601x3 geotiff image)

```julia
julia> using GMT
julia> @btime gdalread("hawaii_south.tiff");
  16.711 ms (101 allocations: 1.05 MiB)

```

and for comparison

```julia
julia> using Images
julia> @btime load("hawaii_south.tiff");
  189.968 ms (199612 allocations: 34.36 MiB)

```

But Matlab is the clear winner.

```julia
>> tic; for n = 1:5, img = imread('hawaii_south.tiff'); end; toc
Elapsed time is 0.015118 seconds.

```

Note that I dropped the `double(...)` to make the times comparable and note also that Matlab time is multiplied by 5. If we divide by it we get `0.0030236`

---

<div class="post-metadata">

### Author: ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)
#### Post date: [June 4, 2023, 10:03am UTC](https://discourse.julialang.org/t/very-slow-loading-speed-of-tiff-images/99826/5 "2023-06-04T10:03:41Z")

</div>

Note that the original post’s timings are almost completely garbage collection. I wonder why loading five images incurs a second worth of garbage, though.

---

<div class="post-metadata">

### Author: ![anon56330260](https://avatars.discourse-cdn.com/v4/letter/a/f07891/32.png) [@anon56330260](https://discourse.julialang.org/u/anon56330260)
#### Post date: [June 4, 2023, 10:37am UTC](https://discourse.julialang.org/t/very-slow-loading-speed-of-tiff-images/99826/6 "2023-06-04T10:37:15Z")

</div>

I guess you are using windows operating system? On windows, before loading the image, `load` firstly calls GC.gc() to recycle memory. This is a known issue. See [TiffImages.jl/load.jl at master · tlnagy/TiffImages.jl · GitHub](https://github.com/tlnagy/TiffImages.jl/blob/master/src/load.jl#LL1C1-L15C4)  
and the `safe_load` in [TiffImages.jl/utils.jl at master · tlnagy/TiffImages.jl · GitHub](https://github.com/tlnagy/TiffImages.jl/blob/master/src/utils.jl#LL194C1-L210C4)  
On Linux system, there is no such issue and the loading time is approximately the same as the Matlab. I test with a 10MB image.

---

<div class="post-metadata">

### Author: ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)
#### Post date: [June 4, 2023, 10:59am UTC](https://discourse.julialang.org/t/very-slow-loading-speed-of-tiff-images/99826/7 "2023-06-04T10:59:45Z")

</div>

> [@joa-quim](#):
>
> `Elapsed time is 0.015118 seconds.`

The variation in times is really big. Especially a 100x for Matlab. This is suspicious. Most likely some deferred processing is taking place. Perhaps the file is simply memory mapped and nothing else.

Have you tried:

```julia
using TiffImages
img = TiffImages.load(filepath; mmap=true);

```

---

<div class="post-metadata">

### Author: ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)
#### Post date: [June 4, 2023, 6:50pm UTC](https://discourse.julialang.org/t/very-slow-loading-speed-of-tiff-images/99826/8 "2023-06-04T18:50:26Z")

</div>

> [@anon56330260](#):
>
> This is a known issue. See [TiffImages.jl/load.jl at master · tlnagy/TiffImages.jl · GitHub](https://github.com/tlnagy/TiffImages.jl/blob/master/src/load.jl#LL1C1-L15C4)  
> and the `safe_load` in [TiffImages.jl/utils.jl at master · tlnagy/TiffImages.jl · GitHub](https://github.com/tlnagy/TiffImages.jl/blob/master/src/utils.jl#LL194C1-L210C4)

Am I reading that code right? To work around a problem with mmapping on Windows, a preemptive `GC.gc` is called regardless of lazy/mmap flags and with no way to opt out?

---

<div class="post-metadata">

### Author: ![Kadii](https://avatars.discourse-cdn.com/v4/letter/k/9fc29f/32.png) [@Kadii](https://discourse.julialang.org/u/Kadii)
#### Post date: [June 4, 2023, 10:59pm UTC](https://discourse.julialang.org/t/very-slow-loading-speed-of-tiff-images/99826/9 "2023-06-04T22:59:05Z")

</div>

That’s right. I’m using windows operating system. Thank you for your comments. Since almost all machines in my environment are Windows, that would be great if there is a way to get the same speed on Windows. If you know any way to speed up, that would be very helpful.

---

<div class="post-metadata">

### Author: ![Kadii](https://avatars.discourse-cdn.com/v4/letter/k/9fc29f/32.png) [@Kadii](https://discourse.julialang.org/u/Kadii)
#### Post date: [June 4, 2023, 11:04pm UTC](https://discourse.julialang.org/t/very-slow-loading-speed-of-tiff-images/99826/10 "2023-06-04T23:04:05Z")

</div>

Thank you very much!  
I also tried GMT as you’ve shown. This speeds up a lot.

```julia
using GMT
readGMT() = begin
	for n ∈ 1:5
		GMT.gdalread(filetif)
	end
end
@time readGMT()
  0.095000 seconds (680 allocations: 10.446 MiB)

```

At this moment, the solution would be the usage of the GMT package.

Thanks!

---

<div class="post-metadata">

### Author: ![Kadii](https://avatars.discourse-cdn.com/v4/letter/k/9fc29f/32.png) [@Kadii](https://discourse.julialang.org/u/Kadii)
#### Post date: [June 17, 2023, 8:53pm UTC](https://discourse.julialang.org/t/very-slow-loading-speed-of-tiff-images/99826/11 "2023-06-17T20:53:24Z")

</div>

There is one update.  
I’ve tried using OpenCV.jl. It’s seems the best option I can take on my Windows10 machine.  
I summarized the runtime comparison what I’ve tried so far. The test image is a 565 x 552 RGB image (~2MB).

| Package | time |
| --- | --- |
| OpenCV.jl | 3.6 ms |
| GMT.jl | 14.5 ms |
| TiffImages.jl | 305.4 ms |
| Matlab | 8.0 ms |

# Versions

- julia v1.9.0
- Matlab R2022a
- OpenCV v4.5.3
- TiffImages v0.6.4
- GMT v1.1.0

# Codes

**julia**

```julia
using OpenCV
using TiffImages
using GMT

filetif = "test_image.tiff"

@btime OpenCV.imread(filetif)
    3.631 ms (20 allocations: 720 bytes)
@btime TiffImages.load(filetif)
    305.342 ms (413 allocations: 4.16 MiB)
@btime GMT.gdalread(filetif)
    14.536 ms (141 allocations: 2.09 MiB)

```

**Matlab**

```julia-auto
filetif = "test_image.tiff"

tic;
for i = 1:1000
    img = imread(filetif);
end
toc;
    Elapsed time is 7.980724 seconds for 1000 images
     -> 7.980724 ms for each.

```

---

<div class="post-metadata">

### Author: ![Ashwani\_Rathee](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ashwani_rathee/32/49551_2.png) [@Ashwani\_Rathee](https://discourse.julialang.org/u/Ashwani_Rathee)
#### Post date: [June 18, 2023, 4:21am UTC](https://discourse.julialang.org/t/very-slow-loading-speed-of-tiff-images/99826/12 "2023-06-18T04:21:03Z")

</div>

@Kadii I love that you tried using OpenCV.jl, it’s great that OpenCV.jl can read it the fastest but then it must be noticed that OpenCV.jl doesn’t work really well with other image processing libraries in Julia that are provided by JuliaImages. So despite saving time on imread, you are forced to stay in OpenCV’s world atm mostly in OpenCV.jl.

---

<div class="post-metadata">

### Author: ![Kadii](https://avatars.discourse-cdn.com/v4/letter/k/9fc29f/32.png) [@Kadii](https://discourse.julialang.org/u/Kadii)
#### Post date: [June 18, 2023, 4:39am UTC](https://discourse.julialang.org/t/very-slow-loading-speed-of-tiff-images/99826/13 "2023-06-18T04:39:57Z")

</div>

@Ashwani_Rathee Thank you for your advise. I’ve been faced the problem you mentioned.  
I realized that I could convert `OpenCV::Mat` to `::Array` by simply calling its slices. I haven’t tried yet but I’m hoping I can pass it to `JuliaImages`’ functions and it works. 🙂

```julia
using OpenCV

filetif = "test_image.tiff"
img = OpenCV.imread(filetif, -1)
arr = img[:, :, :]

typeof(img)
    OpenCV.Mat{UInt8}

typeof(arr)
    Array{UInt8, 3}

```

---

<div class="post-metadata">

### Author: ![Jose\_Diaz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jose_diaz/32/43750_2.png) [@Jose\_Diaz](https://discourse.julialang.org/u/Jose_Diaz)
#### Post date: [June 23, 2023, 9:16am UTC](https://discourse.julialang.org/t/very-slow-loading-speed-of-tiff-images/99826/14 "2023-06-23T09:16:01Z")

</div>

How can load() from Images.jl be improved?

---

<div class="post-metadata">

### Author: ![stillyslalom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stillyslalom/32/45687_2.png) [@stillyslalom](https://discourse.julialang.org/u/stillyslalom)
#### Post date: [June 23, 2023, 2:08pm UTC](https://discourse.julialang.org/t/very-slow-loading-speed-of-tiff-images/99826/15 "2023-06-23T14:08:41Z")

</div>

I’ve worked around the GC issue like so:

```julia
"""
    tif_load(path)

Loads a TIFF image after temporarily disabling garbage collection,
then re-sets GC to its initial state. This is a workaround for
the 75-90% GC overhead otherwise seen when loading TIFF images.
"""
function tif_load(path)
    initial_gc_state = GC.enable(false)
    img = load(path)
    GC.enable(initial_gc_state)
    img
end

```

which does a pretty good job:

```julia
julia> @time TiffImages.load("test.tif"); # test.tif is a 532 x 532 RGB image
  0.193545 seconds (298 allocations: 1.513 MiB, 98.69% gc time)

julia> @time tif_load("test.tif");
  0.001620 seconds (298 allocations: 1.513 MiB)

```

---

<div class="post-metadata">

### Author: ![tlnagy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tlnagy/32/5815_2.png) [@tlnagy](https://discourse.julialang.org/u/tlnagy)
#### Post date: [October 3, 2023, 1:07am UTC](https://discourse.julialang.org/t/very-slow-loading-speed-of-tiff-images/99826/16 "2023-10-03T01:07:09Z")

</div>

Author of TiffImages here, I consider it a bug if we’re slower than Matlab 😅

Are you also on Windows, I presume? Does your `tif_load` function work with the `mmap=true` flag set too?

I wonder if we still need that `GC.load` call at all (or if there’s a better solution), which was introduced in [https://github.com/tlnagy/TiffImages.jl/pull/79](https://github.com/tlnagy/TiffImages.jl/pull/79). Unfortunately, I don’t regularly use a Windows machine so this performance gotcha has evaded me.
