I mean, I used both in the past and they basically do the same exact thing. For example, if a player touches a part, :GetPlayerFromCharacter would simply just check if the thing that touched the part is a player. Whilst searching for the player through playerService is technically doing the same exact thing but is just a different way to achieve the same exact thing.
At the end of the day, though, there really is no difference.
But to answer your question, I personally use :GetPlayerFromCharacter for convenience purposes, although I am almost 100% sure there would be no difference in lag. And even if there was it would be a very minor difference.
They look the same but they’re fundamentally different.
GetPlayerFromCharacter goes through all Players in the game and compares if their Character property (a reference to the Player’s character model) is equivalent to the model you pass in the function. The second one attempts to index a string on the Players service.
You should be using the first one. The second example is prone to unexpected behaviour or errors because a player can share a name with a property or a child object and those might be indexed instead of the real player. In the instance that a player’s name is that of a property (e.g. the player’s name is Name), the property will be indexed due to its precedence, causing an error when trying to further interact with that variable in assumption that it indexed a player.
The second one is safer because it compares references. You have a model and you’re checking to see if any of the players hold a reference to that model via the Character property, thus making that CharacterModel == Player.Character (they’re the same model).
Performance is a negligible concern and you don’t need to worry about it. Objectively speaking though GetPlayerFromCharacter is slower than the second option because it’s internally a loop versus indexing a table member but in terms of practicality the second one is impractical, though when I say slow I don’t mean dramatically, just marginally. No more than a few unnoticeable milliseconds.
The “performance gain” from direct indexation over using a function is negligible. GetPlayerFromCharacter is the canonical way to get a player based on their character because it compares the player’s Character property reference to the model being checked. You should be using that function to make your code predictable, obvious, readable and more idiomatic.
The character model will already share a name with the player if you aren’t doing your own modifications to the character so there’s no reason to add an extra process to set the name of the character when it will already be that way. The main point here isn’t designing for performance but designing for well structured code and using best practices.
If you’re strictly thinking of designing in terms of performance gains even if the gains are negligible or nonexistent, you can end up foregoing good practice or dismissing the idea behind why a developer might choose one way over another. Why settle for the character’s name as a dependency to fetch the character when you can compare object references instead? Names can change, references don’t.