I don't get why that would require runtime type checking. The type of the values you are passing to add could be unambiguously determined to be (integer,integer) and (string,string). Thus the compiler could create two functions (or even inline the code), one for add(string,string) and one for add(int,int).
If you think type inference in real programs is quick, easy or accurate, I suggest you go work for a compilers team for a short while. They will disfranchise you of this opinion.
Perhaps then you will understand why knowing what a type is allows you to generate faster code than trying to guess what it is.