The problem with:

    ret = ""
    for s in strings:
        ret += s
is that it re-allocates O(n) times, even if ret is referenced only once.

If the s are small the usual geometric buffer growth mitigates that. Of course you can compute the final buffer size in this case, but often you have a bunch of dynamically-generated strings of different sizes.