If I need to add custom fields only to user profiles, is it better to create a module that uses the field API, or a module that uses its own code to show the custom fields at a custom URL and to save the data in its own database table?
The field API doesn't implement the permissions necessary to decide which fields are visible to which users; is that a reason enough to implement custom code?
Implementing a custom Field API field is quite simply, there are already many tutorials and example modules available. One of the advantages is that it provides all the storage handling for you and it can provide handling for multiple values and so on.
Note that Field API provides the framework for field level access permissions but it doesn't implement it. Just like node_access. So that's not a reason against using it.
See http://drupal.org/project/field_permissions for a project that provides an implementation for that.
In the long run, it will be better to use the fields API. It will give you more flexibility and allow other modules to integrate. Besides there are some various hooks that gets called when different actions occur which also might come in handy. All in all, this is what the API is for.
Learning how to use it might take a little while longer than a custom solution, but the gains makes that time well spent.