There are indeed tools. They are your best bet (after backing up with Address Book File > Export > Archive). Some duplicate cleaner apps are even free. Just search the Mac App Store or google.
Doing it yourself is grueling. Avoid it.
However, since I couldn't find a good online guide for this horrible process that you should avoid, I wroteup the basic workflow structure:
First, consider testing in a new User on your Mac. It may turn out there is no issue with your Contacts /iCloud data, and trying to clean up is a waste of time because the problem is only with your regular User. However, the User testing is a waste of time if it is an issue with the data. I'll skip to cleaning the data in your current User:
First back up with Export > Archive.
In Address Book, select chunks of contacts chunks of contacts (e.g. A-B, C-D), to export>vcard and then delete, if needed with wifi turned off, until the app becomes more responsive.
Once Address Book becomes responsive, make a new Export> Archive backup, so you can easily return to this point later, if needed. (But don't delete the original archive.)
Then turn wifi back on, if you turned it off, and give iCloud a while to catch up, and see if the app is still responsive. Once your iOS devices reflect the removal of contacts, you can clean up what you did not export/delete in Address Book (e.g. L-Z, or wherever you were at this point).
Finally, reimport and clean up your vcard chunks one by one. If a certain chunk causes Address Book to stop responding repeat the vcard-export, delete process for that chunk but in half size regressions (e.g. A-B vcard into A and B vcard) until you nail down the contact(s) that are breaking Address Book.
If this all works, but you can't find a contact later on, use a New User to open the corrupted original archive, and export the vcard in question from there.