Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 61a93d5d authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Add memory usage tests for various scripts"

parents c5e6a080 c5fe9674
Loading
Loading
Loading
Loading
+79 −29
Original line number Original line Diff line number Diff line
@@ -42,6 +42,7 @@ import org.junit.runner.RunWith;


import java.nio.CharBuffer;
import java.nio.CharBuffer;
import java.util.Random;
import java.util.Random;
import java.util.Locale;


@LargeTest
@LargeTest
@RunWith(AndroidJUnit4.class)
@RunWith(AndroidJUnit4.class)
@@ -49,9 +50,7 @@ public class PrecomputedTextMemoryUsageTest {
    private static final int WORD_LENGTH = 9;  // Random word has 9 characters.
    private static final int WORD_LENGTH = 9;  // Random word has 9 characters.
    private static final boolean NO_STYLE_TEXT = false;
    private static final boolean NO_STYLE_TEXT = false;


    private static TextPaint PAINT = new TextPaint();
    private static int TRIAL_COUNT = 10;

    private static int TRIAL_COUNT = 100;


    public PrecomputedTextMemoryUsageTest() {}
    public PrecomputedTextMemoryUsageTest() {}


@@ -75,9 +74,10 @@ public class PrecomputedTextMemoryUsageTest {
    }
    }


    @Test
    @Test
    public void testMemoryUsage_NoHyphenation() {
    public void testMemoryUsage_Latin_NoHyphenation() {
        TextPaint paint = new TextPaint();
        int[] memories = new int[TRIAL_COUNT];
        int[] memories = new int[TRIAL_COUNT];
        final PrecomputedText.Params param = new PrecomputedText.Params.Builder(PAINT)
        final PrecomputedText.Params param = new PrecomputedText.Params.Builder(paint)
                .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
                .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
                .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
                .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
                .build();
                .build();
@@ -88,13 +88,14 @@ public class PrecomputedTextMemoryUsageTest {
                    mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), param)
                    mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), param)
                .getMemoryUsage();
                .getMemoryUsage();
        }
        }
        reportMemoryUsage(median(memories), "MemoryUsage_NoHyphenation");
        reportMemoryUsage(median(memories), "MemoryUsage_Latin_NoHyphenation");
    }
    }


    @Test
    @Test
    public void testMemoryUsage_Hyphenation() {
    public void testMemoryUsage_Latin_Hyphenation() {
        TextPaint paint = new TextPaint();
        int[] memories = new int[TRIAL_COUNT];
        int[] memories = new int[TRIAL_COUNT];
        final PrecomputedText.Params param = new PrecomputedText.Params.Builder(PAINT)
        final PrecomputedText.Params param = new PrecomputedText.Params.Builder(paint)
                .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED)
                .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED)
                .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
                .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
                .build();
                .build();
@@ -105,48 +106,97 @@ public class PrecomputedTextMemoryUsageTest {
                    mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), param)
                    mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), param)
                .getMemoryUsage();
                .getMemoryUsage();
        }
        }
        reportMemoryUsage(median(memories), "MemoryUsage_Hyphenation");
        reportMemoryUsage(median(memories), "MemoryUsage_Latin_Hyphenation");
    }
    }


    @Test
    @Test
    public void testMemoryUsage_NoHyphenation_WidthOnly() {
    public void testMemoryUsage_CJK_NoHyphenation() {
        TextPaint paint = new TextPaint();
        int[] memories = new int[TRIAL_COUNT];
        int[] memories = new int[TRIAL_COUNT];
        final PrecomputedText.Params param = new PrecomputedText.Params.Builder(PAINT)
        final PrecomputedText.Params param = new PrecomputedText.Params.Builder(paint)
                .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
                .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
                .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
                .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
                .build();
                .build();


        // Report median of randomly generated PrecomputedText.
        // Report median of randomly generated PrecomputedText.
        for (int i = 0; i < TRIAL_COUNT; ++i) {
        for (int i = 0; i < TRIAL_COUNT; ++i) {
            CharSequence cs = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
            memories[i] = PrecomputedText.create(
            PrecomputedText.ParagraphInfo[] paragraphInfo =
                    mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT, "[\\u4E00-\\u9FA0]"),
                    PrecomputedText.createMeasuredParagraphs(cs, param, 0, cs.length(), false);
                    param).getMemoryUsage();
            memories[i] = 0;
        }
            for (PrecomputedText.ParagraphInfo info : paragraphInfo) {
        reportMemoryUsage(median(memories), "MemoryUsage_CJK_NoHyphenation");
                memories[i] += info.measured.getMemoryUsage();
    }

    @Test
    public void testMemoryUsage_CJK_Hyphenation() {
        TextPaint paint = new TextPaint();
        int[] memories = new int[TRIAL_COUNT];
        final PrecomputedText.Params param = new PrecomputedText.Params.Builder(paint)
                .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED)
                .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
                .build();

        // Report median of randomly generated PrecomputedText.
        for (int i = 0; i < TRIAL_COUNT; ++i) {
            memories[i] = PrecomputedText.create(
                    mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT, "[\\u4E00-\\u9FA0]"),
                    param).getMemoryUsage();
        }
        }
        reportMemoryUsage(median(memories), "MemoryUsage_CJK_Hyphenation");
    }

    @Test
    public void testMemoryUsage_Arabic_NoHyphenation() {
        TextPaint paint = new TextPaint();
        paint.setTextLocale(Locale.forLanguageTag("ar"));
        int[] memories = new int[TRIAL_COUNT];
        final PrecomputedText.Params param = new PrecomputedText.Params.Builder(paint)
                .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
                .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
                .build();

        // Report median of randomly generated PrecomputedText.
        for (int i = 0; i < TRIAL_COUNT; ++i) {
            memories[i] = PrecomputedText.create(
                    mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT, "[\\u0600-\\u06FF]"),
                    param).getMemoryUsage();
        }
        }
        reportMemoryUsage(median(memories), "MemoryUsage_NoHyphenation_WidthOnly");
        reportMemoryUsage(median(memories), "MemoryUsage_Arabic_NoHyphenation");
    }
    }


    @Test
    @Test
    public void testMemoryUsage_Hyphenatation_WidthOnly() {
    public void testMemoryUsage_Arabic_Hyphenation() {
        TextPaint paint = new TextPaint();
        paint.setTextLocale(Locale.forLanguageTag("ar"));
        int[] memories = new int[TRIAL_COUNT];
        int[] memories = new int[TRIAL_COUNT];
        final PrecomputedText.Params param = new PrecomputedText.Params.Builder(PAINT)
        final PrecomputedText.Params param = new PrecomputedText.Params.Builder(paint)
                .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED)
                .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED)
                .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
                .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
                .build();
                .build();


        // Report median of randomly generated PrecomputedText.
        // Report median of randomly generated PrecomputedText.
        for (int i = 0; i < TRIAL_COUNT; ++i) {
        for (int i = 0; i < TRIAL_COUNT; ++i) {
            CharSequence cs = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
            memories[i] = PrecomputedText.create(
            PrecomputedText.ParagraphInfo[] paragraphInfo =
                    mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT, "[\\u0600-\\u06FF]"),
                    PrecomputedText.createMeasuredParagraphs(cs, param, 0, cs.length(), false);
                    param).getMemoryUsage();
            memories[i] = 0;
        }
            for (PrecomputedText.ParagraphInfo info : paragraphInfo) {
        reportMemoryUsage(median(memories), "MemoryUsage_Arabic_Hyphenation");
                memories[i] += info.measured.getMemoryUsage();
    }
    }
    @Test
    public void testMemoryUsage_Emoji() {
        TextPaint paint = new TextPaint();
        int[] memories = new int[TRIAL_COUNT];
        final PrecomputedText.Params param = new PrecomputedText.Params.Builder(paint)
                .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
                .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
                .build();

        // Report median of randomly generated PrecomputedText.
        for (int i = 0; i < TRIAL_COUNT; ++i) {
            memories[i] = PrecomputedText.create(
                    mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT, "[:emoji:]"),
                    param).getMemoryUsage();
        }
        }
        reportMemoryUsage(median(memories), "MemoryUsage_Hyphenation_WidthOnly");
        reportMemoryUsage(median(memories), "MemoryUsage_Emoji_NoHyphenation");
    }
    }
}
}
+52 −10
Original line number Original line Diff line number Diff line
@@ -27,6 +27,8 @@ import android.support.test.runner.AndroidJUnit4;
import android.content.res.ColorStateList;
import android.content.res.ColorStateList;
import android.graphics.Canvas;
import android.graphics.Canvas;
import android.graphics.Typeface;
import android.graphics.Typeface;
import android.icu.text.UnicodeSet;
import android.icu.text.UnicodeSetIterator;
import android.text.Layout;
import android.text.Layout;
import android.text.style.TextAppearanceSpan;
import android.text.style.TextAppearanceSpan;
import android.view.DisplayListCanvas;
import android.view.DisplayListCanvas;
@@ -39,6 +41,7 @@ import org.junit.runner.RunWith;


import java.nio.CharBuffer;
import java.nio.CharBuffer;
import java.util.Random;
import java.util.Random;
import java.util.ArrayList;


public class TextPerfUtils {
public class TextPerfUtils {


@@ -46,8 +49,17 @@ public class TextPerfUtils {


    private Random mRandom = new Random(0);
    private Random mRandom = new Random(0);


    private static final String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    private static final String[] ALPHABET;
    private static final int ALPHABET_LENGTH = ALPHABET.length();
    private static final int ALPHABET_LENGTH;
    static {
        String alphabets = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
        ALPHABET_LENGTH = alphabets.length();
        ALPHABET = new String[ALPHABET_LENGTH];
        for (int i = 0; i < ALPHABET_LENGTH; ++i) {
            ALPHABET[i] = Character.toString(alphabets.charAt(i));
        }
    }



    private static final ColorStateList TEXT_COLOR = ColorStateList.valueOf(0x00000000);
    private static final ColorStateList TEXT_COLOR = ColorStateList.valueOf(0x00000000);
    private static final String[] FAMILIES = { "sans-serif", "serif", "monospace" };
    private static final String[] FAMILIES = { "sans-serif", "serif", "monospace" };
@@ -55,30 +67,59 @@ public class TextPerfUtils {
            Typeface.NORMAL, Typeface.BOLD, Typeface.ITALIC, Typeface.BOLD_ITALIC
            Typeface.NORMAL, Typeface.BOLD, Typeface.ITALIC, Typeface.BOLD_ITALIC
    };
    };


    private final char[] mBuffer = new char[PARA_LENGTH];

    public void resetRandom(long seed) {
    public void resetRandom(long seed) {
        mRandom = new Random(seed);
        mRandom = new Random(seed);
    }
    }


    private static String[] UnicodeSetToArray(String setStr) {
        final UnicodeSet set = new UnicodeSet(setStr);
        final UnicodeSetIterator iterator = new UnicodeSetIterator(set);
        final ArrayList<String> out = new ArrayList<>(set.size());
        while (iterator.next()) {
          out.add(iterator.getString());
        }
        return out.toArray(new String[out.size()]);
    }

    public CharSequence nextRandomParagraph(int wordLen, boolean applyRandomStyle, String setStr) {
        return nextRandomParagraph(wordLen, applyRandomStyle, UnicodeSetToArray(setStr));
    }

    public CharSequence nextRandomParagraph(int wordLen, boolean applyRandomStyle) {
    public CharSequence nextRandomParagraph(int wordLen, boolean applyRandomStyle) {
        return nextRandomParagraph(wordLen, applyRandomStyle, ALPHABET);
    }

    public CharSequence nextRandomParagraph(int wordLen, boolean applyRandomStyle,
            String[] charSet) {
        ArrayList<Character> chars = new ArrayList<>();
        ArrayList<Integer> wordOffsets = new ArrayList<>();
        for (int i = 0; i < PARA_LENGTH; i++) {
        for (int i = 0; i < PARA_LENGTH; i++) {
            if (i % (wordLen + 1) == wordLen) {
            if (i % (wordLen + 1) == wordLen) {
                mBuffer[i] = ' ';
                chars.add(' ');
                wordOffsets.add(chars.size());
            } else {
            } else {
                mBuffer[i] = ALPHABET.charAt(mRandom.nextInt(ALPHABET_LENGTH));
                final String str = charSet[mRandom.nextInt(charSet.length)];
                for (int j = 0; j < str.length(); ++j) {
                    chars.add(str.charAt(j));
                }
            }
            }
        }
        }
        wordOffsets.add(chars.size());


        CharSequence cs = CharBuffer.wrap(mBuffer);
        char[] buffer = new char[chars.size()];
        for (int i = 0; i < buffer.length; ++i) {
            buffer[i] = chars.get(i);
        }
        CharSequence cs = CharBuffer.wrap(buffer);
        if (!applyRandomStyle) {
        if (!applyRandomStyle) {
            return cs;
            return cs;
        }
        }


        SpannableStringBuilder ssb = new SpannableStringBuilder(cs);
        SpannableStringBuilder ssb = new SpannableStringBuilder(cs);
        for (int i = 0; i < ssb.length(); i += wordLen + 1) {
        int prevWordStart = 0;
            final int spanStart = i;
        for (int i = 0; i < wordOffsets.size(); i++) {
            final int spanEnd = (i + wordLen) > ssb.length() ? ssb.length() : i + wordLen;
            final int spanStart = prevWordStart;
            final int spanEnd = wordOffsets.get(i);


            final TextAppearanceSpan span = new TextAppearanceSpan(
            final TextAppearanceSpan span = new TextAppearanceSpan(
                  FAMILIES[mRandom.nextInt(FAMILIES.length)],
                  FAMILIES[mRandom.nextInt(FAMILIES.length)],
@@ -87,6 +128,7 @@ public class TextPerfUtils {
                  TEXT_COLOR, TEXT_COLOR);
                  TEXT_COLOR, TEXT_COLOR);


            ssb.setSpan(span, spanStart, spanEnd, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
            ssb.setSpan(span, spanStart, spanEnd, Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
            prevWordStart = spanEnd;
        }
        }
        return ssb;
        return ssb;
    }
    }