Problem/Motivation
Staring at xhprof output for lots of points, or large geometries, multiple calls were made to GeofieldItem::isEmpty() which is each time creating a geometry object to check if it's empty taking time/memory.
Looking at the code it doesn't need to do this. When the value is set of the field https://git.drupalcode.org/project/geofield/-/blob/8.x-1.x/src/Plugin/Fi... it already creates a geometry and checks if it is empty https://git.drupalcode.org/project/geofield/-/blob/8.x-1.x/src/Plugin/Fi... so the computed values in these columns are NULL if the \Geometry::isEmpty() is TRUE.
Proposed resolution
Don't recreate the Geometry and request if ::isEmpty, but check if one of the columns is NULL.
Remaining tasks
Make an MR.
API changes
None.
Although staring at this I also question if for a field item ::isEmpty https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21TypedData... it is actually correct to return if the geometry that is set is empty. It's a bit like a numeric field returning empty if it contains 0? The value is set, it has value, it is Geometry, it's just Empty Geometry https://trac.osgeo.org/postgis/wiki/DevWikiEmptyGeometry
However, altering that would be a BC break. So just re-using the previous Geometry isEmpty check seemed the better way.
Issue fork geofield-3423627
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #3
ekes commentedComment #4
ekes commentedMeh. Why did that pass D10.1? In the test setting the $field->value directly doesn't cause the calculation as setValue(). Maybe it should be really.
Comment #5
ekes commentedI'd say this is blocked on #3423632: Computed values
Comment #7
itamair commentedthanks @ekes for your updates. Going to re-jump and review your last comment asap ...
Comment #8
itamair commentedSoo @ekes ...
I better inspected all this, and I ended up with the conviction that is still nice to define a GeofieldItem::isEmpty() method that not only make sure that the geofield primitive/row (WKT) input is not empty but also that it generates a valid /Geometry.
That is correct, and we should keep it, and also the Test code base that assumes it ...
What we should rather limit, as you correctly mentioned, is the redundant generation of the same /Geometry in the same GeofieldItem class, to limit the time/memory script overhead and better apply the DRY principle.
That's why in my latest commit a preferred to keep basically unchanged the GeofieldItem::isEmpty() method and rather to define a private \Geometry $geometry property that could be generated once and reused also in the GeofieldItem::populateComputedValues() method.
Tests are still passing nicely with this change and $geo_php_wrapper->load($value) is only called once in the class.
I would commit this that looks a nice improvement to me.
Let me know if you disagree, if you see some issues or potential regressions, or evident mistake with this solution of mine.
Comment #9
itamair commentedWell ... I didn't read any feedback to my latest update.
I am feeling my last update / commit is pretty solid, hence I am going to merge this into 8.x-1.x dev, for being part of new upcoming release.