They serve different purposes and depends on your context you can decide which one to use or a combination of both.
create_program_address
is for creating PDA with provided seeds and bump
Example
Checking PDA created from provided seeds and bump matches canonical bump PDA. Will return error if provided seed result in an invalid PDA (on-curve).
let (expected_pda, bump_seed) = Pubkey::find_program_address(&[b"vault"], &program_id);
let actual_pda = Pubkey::create_program_address(&[b"vault", &[provided_bump]], &program_id)?;
assert_eq!(expected_pda, actual_pda);
find_program_address
is for finding canonical bump PDA
Example
Checking provided PDA matches canonical bump PDA
let (canonical_bump_pda, canonical_bump) = Pubkey::find_program_address(&[b"vault"], &program_id);
assert_eq!(canonical_bump_pda, provided_pda);
find_program_address
may consume a variable Compute Units due to possible additional computation needed to find an off-curve PDA. This should be aware in CUs sensitive context such as onchain program.