What you have is specifically the best way to deal with most such scenarios:
- Using the SOQL for loop approach allows runtime to be efficient with heap space.
- Adding detail to the account names set only in that loop makes the loop as performant as possible.
In this specific case you are after unique account names only, so you can switch to using an aggregate query with grouping:
Set<String> accountNames = new Set<String>();
for (AggregateResult acc : [SELECT Name FROM Account GROUP BY Name LIMIT 50000]) {
accountNames.add((String) acc.get('Name'));
}
This may be slightly faster if you do have significant numbers of duplicate Account names. If you don't, then your existing solution is likely to be slightly faster (based on some rather trivial testing with small numbers of Accounts).
A general note: make sure you only query those fields you actually need since this can have an impact on performance.
PS: There's currently no API for turning that queried array of Accounts into a set of account Names (there's only a means to turn an array of Accounts into a set of IDs via Set<Id> ids = new Map<String, Account>(accounts).keySet()
).
PPS: See Cropredy's answer for something approaching the API I said doesn't exist...!