Instantiating Fields: via UI, API or Drush? Are there any benefits of using one method of instantiating over another?

From what I'm guessing, creating field instances via the API (programatically) has benefits over the UI since you get to version control the changes.

Drush commands can be put into a script as well and then version controlled.

Are there any other pros/cons to doing things programatically versus the UI?
You can use Features to export your UI-created field configurations and version control the result. It's much faster to create and modify field instances in the UI unless you're extremely familiar with the Field API. I used to create fields programmatically but I feel like my time would have been better spent using the UI and occasionally exporting with Features for VCS/simpletesting.