Well, I agree that global struct arrays are better when you know exactly how many objects you need to create. I would absolutely use them for something with an obvious fixed amount, like defining a global struct array with one struct for each player, to contain easily accessible properties that you want to associate with them.
But I personally find it pretty unmanageable when the number of things is large and/or expected to change over development. Like structs representing heroes and items for the construction and running of a hero selection and item shop. It's a pain when every time you add a hero or item you have to go add 1 to the count.
I also don't think that the slowdown is really worth noting. It's pretty insignificant, as long as your coding is correct. Focusing on reducing the number of checks and runs of triggers is much better. I also find that using the data table makes code a lot more readable and modular. Because you have to define all these getters and setters, the code is just the right amount of verbose for me. I also tend to build any "objects" that use the data table as separate code modules by putting them in separate script "files".
One downside we haven't mentioned is the inability to store function/array pointers in the data table. This really bums me out, I love function pointers. I once worked in a map where there were chat commands and each command was, in the code, part of a really long if/else if/else if/.../else tree. Horrible way of coding. When I wanted to create my own chat command system I created a global struct array to contain the commands and mapped from the entered message to an index in this array, then invoked a function pointer within the corresponding struct.