<div dir="ltr"><div dir="ltr"><div>Hi Thomas</div><div><br></div><div>It took me some time to read the email. I hope it is not a revenge for my last emails containing some explicit WKT2 ;)</div><div><br></div><div>That
is good news! If a projection library, with all the trigonometric and
complicated functions it is calling, is affected by reading and writing
doubles in input/output, it means that the library is really efficient.</div><div>Maybe not in the parsing of the strings, but the rest it is.</div><div>When I started reading the email a while ago, my first reaction was "many people say std streams are not efficient".</div><div></div><div><br></div><div>About
caching grid files, we could probably add an environment variable (read
only once) to set the cache size to a value. That could give you some
flexibility requesting random points.</div><div>Remove compression?
well, maybe the Swedish files are small. The new geoid model for US will
not fit in the size limit per file we have in GitHub. We will have to
do some tricks to include it (like use int16 instead of float32).</div><div><br></div><div>In
summary I agree with Even: command line apps are "toys" for
testing/playing. Can we improve that performance? Probably. Is it worth
it? I don't know. Is your fear that they use it to compare with other
libraries, and PROJ is minus-valued? Could be.</div><div>About grids in
memory, there is always the trade off between memory economics and
performance. We can be more flexible for extreme cases as yours.</div><div><br></div><div>Maybe I am missing other points inside the library where we are slow and we can improve. Please, let me know.</div><div><br></div><div>Cheers</div><font color="#888888"><div>Javier.</div></font><br></div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Wed, 11 Mar 2026 at 18:43, Even Rouault <<a href="mailto:even.rouault@spatialys.com">even.rouault@spatialys.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div>Thomas,<br>
<br>
I don't know how you manage to write such long essays. Does my (non LLM <br>
generated) below summary reflect your findings:<br>
<br>
- Command line utilities are to be considered "toys" if you process a <br>
large amount of data and care about perf. Not that suprising, and I <br>
wouldn't expect anyone trying to use PROJ at its max perf capabilities <br>
to use them, but rather use the (binary) API. In GDAL, we use at some <br>
places the fast_float C++ header library for fast string->double : <br>
<a href="https://github.com/fastfloat/fast_float" rel="noreferrer" target="_blank">https://github.com/fastfloat/fast_float</a> . They claim it can be up to <br>
about 4x faster than strtod(). We could also vendor in PROJ if needed.<br>
<br>
- Grid usage could be made much faster if we decompressed everything in <br>
memory. There's already a bit of caching of decompressed tiles. But <br>
random spatial access pattern will easily defeat it as it is quite <br>
modest currently. We could add an option to increase the cache to a <br>
specified size and/or increase the default size. I wouldn't trust too <br>
much OS virtual memory mapping. Can easily lead to crashing your <br>
system (or making it unusable at the point your need to hard reboot) if <br>
you map too much memory vs your available RAM.<br>
<br>
Even<br>
<br>
Le 11/03/2026 à 09:45, Thomas Knudsen a écrit :<br>
> TL;DR: Is PROJ unreasonably slow? The answer is "Mostly no", but with a few<br>
> caveats...<br>
><br>
> DISCLAIMER: The evidence presented below is weak - timing experiments repeated<br>
> only 2-4 times, on just a single computer. But at first sight the speed tests<br>
> all hint at the same conclusion: That PROJ could be made significantly faster.<br>
><br>
> Closer inspection, however, shows that, while in some corner cases, PROJ really<br>
> can be made faster, in the general cases, it already really is quite fast.<br>
><br></div>... deleted content.<div>
><br>
> But I would highly prefer to leave this kind of code to reside in system<br>
> libraries, not in an application library, like PROJ.<br>
><br>
> Nevertheless: Hope y'all will consider this (much too) long writeup, and give it<br>
> a deep thought, whether rearchitecting PROJ, and to what extent, may be worth<br>
> the effort.<br>
><br>
> /Thomas Knudsen<br>
><br>
><br>
> [1] Rust Geodesy: <a href="https://lib.rs/geodesy" rel="noreferrer" target="_blank">https://lib.rs/geodesy</a><br>
> <a href="https://github.com/busstoptaktik/geodesy" rel="noreferrer" target="_blank">https://github.com/busstoptaktik/geodesy</a><br>
> [2] kp: <a href="https://github.com/busstoptaktik/geodesy/blob/main/ruminations/003-rumination.md" rel="noreferrer" target="_blank">https://github.com/busstoptaktik/geodesy/blob/main/ruminations/003-rumination.md</a><br>
> [3] cs2cs: <a href="https://proj.org/en/stable/apps/cs2cs.html" rel="noreferrer" target="_blank">https://proj.org/en/stable/apps/cs2cs.html</a><br>
> [4] cct: <a href="https://proj.org/en/stable/apps/cct.html" rel="noreferrer" target="_blank">https://proj.org/en/stable/apps/cct.html</a><br>
> [5] The ITRF2014->SWEREF99 transformation:<br>
> $ projinfo -o proj --hide-ballpark -s itrf2014 -t sweref99<br>
> +proj=pipeline<br>
> +step +proj=axisswap +order=2,1<br>
> +step +proj=unitconvert +xy_in=deg +xy_out=rad<br>
> +step +proj=cart +ellps=GRS80<br>
> +step +proj=helmert +x=0 +y=0 +z=0 +rx=0.001785 +ry=0.011151<br>
> +rz=-0.01617 +s=0<br>
> +dx=0 +dy=0 +dz=0 +drx=8.5e-05 +dry=0.000531 +drz=-0.00077 +ds=0<br>
> +t_epoch=2010 +convention=position_vector<br>
> +step +inv +proj=deformation +t_epoch=2000 +grids=eur_nkg_nkgrf17vel.tif<br>
> +ellps=GRS80<br>
> +step +proj=helmert +x=0.03054 +y=0.04606 +z=-0.07944 +rx=0.00141958<br>
> +ry=0.00015132 +rz=0.00150337 +s=0.003002<br>
> +convention=position_vector<br>
> +step +proj=deformation +dt=-0.5 +grids=eur_nkg_nkgrf17vel.tif<br>
> +ellps=GRS80<br>
> +step +inv +proj=cart +ellps=GRS80<br>
> +step +proj=unitconvert +xy_in=rad +xy_out=deg<br>
> +step +proj=axisswap +order=2,1<br>
> [6] Rumination 012: Unigrids and the UG grid maintenance utility<br>
> <a href="https://github.com/busstoptaktik/geodesy/blob/main/ruminations/012-rumination.md" rel="noreferrer" target="_blank">https://github.com/busstoptaktik/geodesy/blob/main/ruminations/012-rumination.md</a><br>
> [7] Even Rouault om lam0:<br>
> <a href="https://github.com/OSGeo/PROJ/pull/4667/changes#diff-bfb0c333155a0c8bf863b0a3e76df46cfddf646cd5f13d6313eb8a3cb123f5f1R58" rel="noreferrer" target="_blank">https://github.com/OSGeo/PROJ/pull/4667/changes#diff-bfb0c333155a0c8bf863b0a3e76df46cfddf646cd5f13d6313eb8a3cb123f5f1R58</a><br>
> [8] proj_strtod():<br>
> <a href="https://github.com/OSGeo/PROJ/blob/master/src/apps/proj_strtod.cpp" rel="noreferrer" target="_blank">https://github.com/OSGeo/PROJ/blob/master/src/apps/proj_strtod.cpp</a><br>
> [9] Update Rust Float-Parsing Algorithms to use the Eisel-Lemire algorithm<br>
> <a href="https://github.com/rust-lang/rust/pull/86761" rel="noreferrer" target="_blank">https://github.com/rust-lang/rust/pull/86761</a><br>
> [10] Implementing a Fast, Correct Float Parser<br>
> <a href="https://internals.rust-lang.org/t/implementing-a-fast-correct-float-parser/14670" rel="noreferrer" target="_blank">https://internals.rust-lang.org/t/implementing-a-fast-correct-float-parser/14670</a><br>
> [11] David Tolnay's dtoa-benchmark: <a href="https://github.com/dtolnay/dtoa-benchmark" rel="noreferrer" target="_blank">https://github.com/dtolnay/dtoa-benchmark</a><br>
> [12] Victor Zverovich's zmij algorithm: <a href="https://github.com/vitaut/zmij/" rel="noreferrer" target="_blank">https://github.com/vitaut/zmij/</a><br>
> [13] OxiGDAL - Pure Rust Geospatial Data Abstraction Library:<br>
> <a href="https://github.com/cool-japan/oxigdal" rel="noreferrer" target="_blank">https://github.com/cool-japan/oxigdal</a><br>
> [14] proj4rs - Rust adaptation of PROJ.4: <a href="https://crates.io/crates/proj4rs" rel="noreferrer" target="_blank">https://crates.io/crates/proj4rs</a><br>
<br>
-- <br>
<a href="http://www.spatialys.com" rel="noreferrer" target="_blank">http://www.spatialys.com</a><br>
My software is free, but my time generally not.<br>
<br>
</div></blockquote></div></div>