For hitboxes i’d definitely suggest using GetPartsInPart or GetPartBoundsInRadius, although it’s personal preference, you have a bit more access over the hitbox with GetPartsInPart, you need to weld a part to the players humanoidrootpart, size it however you want, and then use GetPartsInPart on that part (or the weapon that was used), with GetPartsBoundInRadius, you would most likely make position the humanoidrootpart’s position, and the radius is how big you want the hitbox to be.
Me personally i would use GetPartsInPart, Here’s an explanation
GetPartBoundsInRadius do seem easier to set up; my concern is whether looping through a select list of items and then checking the magnitude individually is less load on the server than GetPartBoundsInRadius
I would imagine that there’s very few cases, if any, in which testing magnitude like this would be more performant than GetPartBoundsInRadius.
The most obvious answer to this would be that ::GetPartBoundsInRadius() is a C-side function. This might already having you imagining that the operation would be much faster even with the interpreter overhead / task switching.
The most critical reason, however, is that this method likely utilises the spatial partitioning structures - among other related optimisations - maintained for the physics engine, i.e. spatial queries for broad-phase → narrow-phase collision detection.
You can see the following links here and here for a brief introduction to these concept(s) if you’re interested.
So, to answer your question: you can be entirely certain that naively iterating through the hierarchy to brute force intersections in Lua will be many times slower than using ::GetPartBoundsInRadius() or similar.