[HN Gopher] Balm in GILead: Fast string construction for CPython...
___________________________________________________________________
Balm in GILead: Fast string construction for CPython extensions
Author : nickelpro
Score : 45 points
Date : 2023-12-15 19:37 UTC (2 days ago)
(HTM) web link (blog.vito.nyc)
(TXT) w3m dump (blog.vito.nyc)
| chrismorgan wrote:
| An explanation of the title, for those not familiar with it:
| Gilead was a region situated in modern-day Jordan, and was
| apparently renowned for its medicinal balm, mentioned a few times
| in the Bible. Further reading:
| https://en.wikipedia.org/wiki/Balm_of_Gilead.
| svat wrote:
| Most familiar to me from Edgar Allan Poe's _The Raven_ , where
| the deranged narrator asks this to the bird:
| "Prophet!" said I, "thing of evil!--prophet still, if bird or
| devil!-- Whether Tempter sent, or whether tempest
| tossed thee here ashore, Desolate yet all
| undaunted, on this desert land enchanted-- On this
| home by Horror haunted--tell me truly, I implore-- Is
| there--*is* there balm in Gilead?--tell me--tell me, I
| implore!" Quoth the Raven "Nevermore."
| traeregan wrote:
| And most familiar to me as the capital of the Barony of New
| Canaan in Stephen King's _The Dark Tower_. Albeit no balm in
| this story (that I recall).
| https://darktower.fandom.com/wiki/Gilead
| stavros wrote:
| Also Handmaid's Tale.
| ashvardanian wrote:
| This looks exceptionally interesting and potentially useful to
| some of our projects. Anyone else using similar methods? Would
| love to know if there are other caveats not covered by the
| article before I start refactoring 10K LOC :)
| haberman wrote:
| I think this technique would not work with the limited API:
| https://docs.python.org/3/c-api/stable.html#limited-c-api
|
| The Limited API has a nice benefit of letting you build
| artifacts that are compatible with a wide range of Python
| versions. The technique described in this article tightly
| couples the extension code to the interpreter internals.
| nickelpro wrote:
| It doesn't work with any version of the public API, Limited,
| Stable, or Unstable, because this is not a part of the API.
| It's more of an application of Hyrum's Law[1].
|
| That said, assuming the structures themselves exist on the
| versions of Python you're targeting in a format compatible
| with whatever hacking you're doing on them, it's very easy to
| compile for lots of Python versions using cibuildwheel[2] and
| the rest of the PyPA ecosystem.
|
| I don't think the Limited API is very useful, as a practical
| matter for the common distribution methods you need the wheel
| to be built with the target Python version.
|
| [1]: https://www.hyrumslaw.com/
|
| [2]: https://github.com/pypa/cibuildwheel
| nickelpro wrote:
| When we first started playing with this we produced memory and
| reference leaks left and right, mostly through undisciplined
| access to reference counts or failures to reference count at
| all. The basic problems the GIL solves don't go away, you need
| to have a principled approach to managing reference counts for
| both the Balm'd objects and the underlying data.
|
| A good rule of thumb we came up with is "reference counts are
| only allowed to be manipulated when holding the GIL." So if you
| create 500 string views that all reference some underlying
| data, the reference count for that underlying data should only
| be incremented by 500 once you acquire the GIL again to
| introduce the data to Python.
|
| If you try to do granular per-refcount locking, you'll run into
| the problem in the multi-threading benchmark. You start to
| incur a lot of lock contention on certain workloads, or even in
| the best case you have a little overhead for zero gain. Making
| the reference counts atomic was a catastrophic performance hit.
|
| Related: It's common to choose to free the underlying resources
| of the balm'd object even though the Python interpreter might
| have stashed a reference to it somewhere. For example in a
| webserver, after the request has been served free'ing/re-using
| the associated header buffers.
|
| We call these "degenerate" applications, because it is not
| reasonable to hold onto such a reference. Sometimes the best
| thing is to document you don't support that use-case in the
| name of performance. Sometimes you might want to be nice and
| throw a description Python exception.
___________________________________________________________________
(page generated 2023-12-17 23:01 UTC)