How to evaluate the efficiency of the buit-in method

In Homework: String Flip Halves, I had three methods.

  • My first method took TOO MUCH MEMORY (1004%) by concatenating strings.
  • My second method converts string to charArray and swap char, but it is INEFFEICIENT (472%).
  • My third method follows the guidline and implement by using substring and it works.

I’m so surprised that substring is so much better than the other ways. So, I would like to know how to choose more efficient functionality/method in Java, Python and any other languages. In addition, is there any principles that we can follow to write efficient code, other than using less loop?

Thank you professor!

Hi Debugger,

Thanks for asking such a great question!
To see what is inside the substring, you need to see the source code of java. You can see it by opening the following link
https://hg.openjdk.java.net/jdk7u/jdk7u6/jdk/file/tip/src/share/classes/java/lang/String.java
Focus on from line 1869 to line 1915.
i also copy this snippet of source code in the following

    public String substring(int beginIndex) {
        if (beginIndex < 0) {
            throw new StringIndexOutOfBoundsException(beginIndex);
        }
        int subLen = value.length - beginIndex;
        if (subLen < 0) {
            throw new StringIndexOutOfBoundsException(subLen);
        }
        return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);
    }

    /**
     * Returns a new string that is a substring of this string. The
     * substring begins at the specified <code>beginIndex</code> and
     * extends to the character at index <code>endIndex - 1</code>.
     * Thus the length of the substring is <code>endIndex-beginIndex</code>.
     * <p>
     * Examples:
     * <blockquote><pre>
     * "hamburger".substring(4, 8) returns "urge"
     * "smiles".substring(1, 5) returns "mile"
     * </pre></blockquote>
     *
     * @param      beginIndex   the beginning index, inclusive.
     * @param      endIndex     the ending index, exclusive.
     * @return     the specified substring.
     * @exception  IndexOutOfBoundsException  if the
     *             <code>beginIndex</code> is negative, or
     *             <code>endIndex</code> is larger than the length of
     *             this <code>String</code> object, or
     *             <code>beginIndex</code> is larger than
     *             <code>endIndex</code>.
     */
    public String substring(int beginIndex, int endIndex) {
        if (beginIndex < 0) {
            throw new StringIndexOutOfBoundsException(beginIndex);
        }
        if (endIndex > value.length) {
            throw new StringIndexOutOfBoundsException(endIndex);
        }
        int subLen = endIndex - beginIndex;
        if (subLen < 0) {
            throw new StringIndexOutOfBoundsException(subLen);
        }
        return ((beginIndex == 0) && (endIndex == value.length)) ? this
                : new String(value, beginIndex, subLen);
    }

To find why there is a memory issue, you need to compare the difference between the source code and your inefficiency code.
I guess your issue comes from memory allocation, but I’m not sure.

I hope this could be helpful. And we can wait for the official answer by the professor together :smile:.
Sincerely,
Haosen Yao.