From 4932b30cedf4dd9b788ad00054df883feac56127 Mon Sep 17 00:00:00 2001 From: Evgeniy Tkachenko Date: Sat, 23 Apr 2016 12:28:28 +0300 Subject: [PATCH 1/6] Test tasks --- .../ua/performancelab/CanvasApiView.java | 12 ++++- .../main/res/layout/backgrounds_layout.xml | 6 +-- app/src/main/res/layout/hierarchy_layout.xml | 52 ++++++++----------- 3 files changed, 36 insertions(+), 34 deletions(-) diff --git a/app/src/main/java/com/performance/ua/performancelab/CanvasApiView.java b/app/src/main/java/com/performance/ua/performancelab/CanvasApiView.java index df5c55d..c58cdae 100644 --- a/app/src/main/java/com/performance/ua/performancelab/CanvasApiView.java +++ b/app/src/main/java/com/performance/ua/performancelab/CanvasApiView.java @@ -32,11 +32,21 @@ public CanvasApiView(Context context, AttributeSet attrs, int defStyleAttr) { @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); + int cardX; + int shiftI; for (int i = 0; i < N; i++) { // Each card is laid out a little to the right of the previous one. myPaint.setColor(Color.RED / (i + 1)); myPaint.setStrokeWidth(10); - canvas.drawRect(MARGIN + i * shift, MARGIN, SIZE + i * shift, SIZE, myPaint); + canvas.save(); + shiftI = i * shift; + cardX = shiftI + MARGIN; + if (i != N - 1) { + canvas.clipRect(cardX, MARGIN, cardX + shift, SIZE); + } + canvas.drawRect(cardX, MARGIN, SIZE + shiftI, SIZE, myPaint); + //Or just draw needed rectangles + canvas.restore(); } // Invalidate the whole view. Doing this calls onDraw() if the view is visible. invalidate(); diff --git a/app/src/main/res/layout/backgrounds_layout.xml b/app/src/main/res/layout/backgrounds_layout.xml index 031a411..d36753e 100644 --- a/app/src/main/res/layout/backgrounds_layout.xml +++ b/app/src/main/res/layout/backgrounds_layout.xml @@ -2,18 +2,18 @@ + > + /> + /> \ No newline at end of file diff --git a/app/src/main/res/layout/hierarchy_layout.xml b/app/src/main/res/layout/hierarchy_layout.xml index 94440c0..b766e4a 100644 --- a/app/src/main/res/layout/hierarchy_layout.xml +++ b/app/src/main/res/layout/hierarchy_layout.xml @@ -1,38 +1,30 @@ - + android:layout_margin="@dimen/avatar_layout_margin" + > - - + + - - - - + android:text="@string/line1_text" + android:id="@+id/awesome_text" + android:layout_toEndOf="@+id/chat_author_avatar1"/> - - - - - + - \ No newline at end of file + \ No newline at end of file From 4bba790d07cb42bb8b089bcfdd271003af36f8a0 Mon Sep 17 00:00:00 2001 From: Evgeniy Tkachenko Date: Sat, 23 Apr 2016 12:30:06 +0300 Subject: [PATCH 2/6] Test tasks --- app/src/main/res/values/strings.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 0e84645..efc024e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -12,4 +12,5 @@ Show how to use historian use traceview to locate churn init download + test From b67267aeb9d981ee9a33dec10a2b5c1ef03b568e Mon Sep 17 00:00:00 2001 From: Evgeniy Tkachenko Date: Sat, 23 Apr 2016 12:31:27 +0300 Subject: [PATCH 3/6] Test tasks --- app/src/main/res/layout/hierarchy_layout.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/layout/hierarchy_layout.xml b/app/src/main/res/layout/hierarchy_layout.xml index b766e4a..77cf447 100644 --- a/app/src/main/res/layout/hierarchy_layout.xml +++ b/app/src/main/res/layout/hierarchy_layout.xml @@ -23,7 +23,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/line2_text" - android:layout_toEndtOf="@+id/chat_author_avatar1" + android:layout_toEndOf="@+id/chat_author_avatar1" android:layout_below="@+id/awesome_text" /> From a15cde037626d6268151c906cb8be0dc7365fc20 Mon Sep 17 00:00:00 2001 From: Evgeniy Tkachenko Date: Sat, 23 Apr 2016 15:42:29 +0300 Subject: [PATCH 4/6] Test tasks --- .../ua/performancelab/ContainerActivity.java | 27 +++++++--- .../ua/performancelab/FibActivity.java | 50 +++++++++++++++++-- 2 files changed, 66 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/com/performance/ua/performancelab/ContainerActivity.java b/app/src/main/java/com/performance/ua/performancelab/ContainerActivity.java index d46c89c..eab11d6 100644 --- a/app/src/main/java/com/performance/ua/performancelab/ContainerActivity.java +++ b/app/src/main/java/com/performance/ua/performancelab/ContainerActivity.java @@ -11,7 +11,9 @@ import android.view.View; import android.webkit.WebView; +import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.Random; /** @@ -22,6 +24,8 @@ public static void start(Context context) { context.startActivity(new Intent(context, ContainerActivity.class)); } + static HashMap> hashMap = new HashMap<>(); + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -53,11 +57,20 @@ public void dumpPopularRandomNumbersByRank() { // take the random number in sorted order, and find its index in the array // that's sorted by popularity. The index is the rank, so report that. Easy and efficient! // Except that it's... you know... It's not. - for (int i = 0; i < sortedNumbers.length; i++) { - Integer currentNumber = sortedNumbers[i]; - for (int j = 0; j < coolestRandomNumbers.length; j++) { - if (currentNumber.compareTo(coolestRandomNumbers[j]) == 0) { - Log.i("Popularity Dump", currentNumber + ": #" + j); + for (int i = 0; i < coolestRandomNumbers.length; i++) { + if(hashMap.containsKey(coolestRandomNumbers[i])) { + hashMap.get(coolestRandomNumbers[i]).add(i); + } else { + ArrayList temp = new ArrayList<>(); + temp.add(i); + hashMap.put(coolestRandomNumbers[i], temp); + } + } + for (Integer sortNumber : sortedNumbers) { + if(hashMap.containsKey(sortNumber)) { + ArrayList indexes = hashMap.get(sortNumber); + for (Integer index:indexes) { + Log.i("Popularity Dump", sortNumber + ": #" + index); } } } @@ -65,13 +78,11 @@ public void dumpPopularRandomNumbersByRank() { } public static Integer[] coolestRandomNumbers = new Integer[3000]; - static int temp; static { Random randomGenerator = new Random(); for (int i = 0; i < 3000; i++) { - temp = randomGenerator.nextInt(); - coolestRandomNumbers[i] = temp; + coolestRandomNumbers[i] = randomGenerator.nextInt(); } } } diff --git a/app/src/main/java/com/performance/ua/performancelab/FibActivity.java b/app/src/main/java/com/performance/ua/performancelab/FibActivity.java index 893657d..78533d6 100644 --- a/app/src/main/java/com/performance/ua/performancelab/FibActivity.java +++ b/app/src/main/java/com/performance/ua/performancelab/FibActivity.java @@ -2,21 +2,27 @@ import android.content.Context; import android.content.Intent; +import android.os.AsyncTask; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; +import android.util.SparseArray; import android.view.View; import android.webkit.WebView; import android.widget.TextView; +import java.util.Date; +import java.util.HashMap; + /** * Created by sergey on 4/22/16. */ public class FibActivity extends AppCompatActivity { public static final String TAG = FibActivity.class.getSimpleName(); - public static final int POSITION_IN_FIB_SEQUENCE = 20; + public static final int POSITION_IN_FIB_SEQUENCE = 40; private TextView textView; + private HashMap mCacheMap = new HashMap<>(); public static void start(Context context) { context.startActivity(new Intent(context, FibActivity.class)); @@ -30,7 +36,15 @@ protected void onCreate(Bundle savedInstanceState) { findViewById(R.id.fib_progress).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - textView.setText(String.valueOf(computeFibonacci(POSITION_IN_FIB_SEQUENCE))); + for (int i = 0; i < 4; i++) { + long time = new Date().getTime(); + String value = String.valueOf(computeFibonacci(POSITION_IN_FIB_SEQUENCE)); + Log.d(TAG, String.valueOf(new Date().getTime() - time) + " ====" + value); + time = new Date().getTime(); + String.valueOf(computeFibonacciOptimized(POSITION_IN_FIB_SEQUENCE)); + Log.d(TAG, String.valueOf(new Date().getTime() - time) + " ====" + value); + new StupidAsyncTask().doInBackground(new Integer[]{POSITION_IN_FIB_SEQUENCE}); + } } }); WebView webView = (WebView) findViewById(R.id.anim_view); @@ -40,7 +54,7 @@ public void onClick(View v) { } public int computeFibonacci(int positionInFibSequence) { - Log.i(TAG, "inside fib" + positionInFibSequence); +// Log.i(TAG, "inside fib" + positionInFibSequence); if (positionInFibSequence <= 2) { return 1; } else { @@ -49,4 +63,34 @@ public int computeFibonacci(int positionInFibSequence) { } } + public int computeFibonacciOptimized(int positionInFibSequence) { + if(mCacheMap.containsKey(positionInFibSequence)) { + return mCacheMap.get(positionInFibSequence); + } +// Log.i(TAG, "inside fib" + positionInFibSequence); + if (positionInFibSequence <= 2) { + mCacheMap.put(positionInFibSequence, 1); + return 1; + } else { + int number = computeFibonacciOptimized(positionInFibSequence - 1) + + computeFibonacciOptimized(positionInFibSequence - 2); + mCacheMap.put(positionInFibSequence, number); + return number; + } + } + + private class StupidAsyncTask extends AsyncTask { + + @Override + protected Integer doInBackground(Integer[] params) { + return computeFibonacci(params[0]); + } + + @Override + protected void onPostExecute(Integer aVoid) { + super.onPostExecute(aVoid); + String.valueOf(aVoid); + } + } + } From 2d66a15c25f374a4b38b484db102bbf658ef4551 Mon Sep 17 00:00:00 2001 From: Evgeniy Tkachenko Date: Sat, 23 Apr 2016 17:10:42 +0300 Subject: [PATCH 5/6] Test tasks --- .../ua/performancelab/ListenerCollector.java | 23 +++++++++++++++++++ .../ua/performancelab/MemoryLeakActivity.java | 10 -------- .../ua/performancelab/MyCustomView.java | 9 ++++++-- 3 files changed, 30 insertions(+), 12 deletions(-) create mode 100644 app/src/main/java/com/performance/ua/performancelab/ListenerCollector.java diff --git a/app/src/main/java/com/performance/ua/performancelab/ListenerCollector.java b/app/src/main/java/com/performance/ua/performancelab/ListenerCollector.java new file mode 100644 index 0000000..1ad42e6 --- /dev/null +++ b/app/src/main/java/com/performance/ua/performancelab/ListenerCollector.java @@ -0,0 +1,23 @@ +package com.performance.ua.performancelab; + +import android.view.View; + +import java.util.WeakHashMap; + +/** + * @author Evgeniy Tkachenko + * @since 4/23/16. + */ +public class ListenerCollector { + // A common case is to want to store all the listeners for a particular type of view + // somewhere. Harmless AND convenient. Or... is it? o_0 + static private WeakHashMap sListeners = new WeakHashMap(); + + public static void setListener(View view, MyCustomView.MyListener listener) { + sListeners.put(view, listener); + } + + public static void removeListeners(View view) { + sListeners.remove(view); + } +} diff --git a/app/src/main/java/com/performance/ua/performancelab/MemoryLeakActivity.java b/app/src/main/java/com/performance/ua/performancelab/MemoryLeakActivity.java index 181b8db..1b47e71 100644 --- a/app/src/main/java/com/performance/ua/performancelab/MemoryLeakActivity.java +++ b/app/src/main/java/com/performance/ua/performancelab/MemoryLeakActivity.java @@ -23,14 +23,4 @@ protected void onCreate(Bundle savedInstanceState) { View view = findViewById(R.id.memory_view); } - static class ListenerCollector { - // A common case is to want to store all the listeners for a particular type of view - // somewhere. Harmless AND convenient. Or... is it? o_0 - static private WeakHashMap sListeners = new WeakHashMap(); - - public void setListener(View view, MyCustomView.MyListener listener) { - sListeners.put(view, listener); - } - } - } diff --git a/app/src/main/java/com/performance/ua/performancelab/MyCustomView.java b/app/src/main/java/com/performance/ua/performancelab/MyCustomView.java index 26bf94b..7213cfb 100644 --- a/app/src/main/java/com/performance/ua/performancelab/MyCustomView.java +++ b/app/src/main/java/com/performance/ua/performancelab/MyCustomView.java @@ -17,8 +17,7 @@ public interface MyListener { * Internal initialization procedures for this view, regardless of which constructor was called. */ private void init() { - MemoryLeakActivity.ListenerCollector collector = new MemoryLeakActivity.ListenerCollector(); - collector.setListener(this, mListener); + ListenerCollector.setListener(this, mListener); } public MyCustomView(Context context) { @@ -42,4 +41,10 @@ public void someListenerCallback() { System.out.println("Someone called me!"); } }; + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + ListenerCollector.removeListeners(this); + } } From 0ad7c5d41fbe830e6b43c380c7bb34b0dcf1aaf4 Mon Sep 17 00:00:00 2001 From: Evgeniy Tkachenko Date: Sat, 23 Apr 2016 17:19:32 +0300 Subject: [PATCH 6/6] Test tasks --- .../ua/performancelab/MemoryChurnActivity.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/performance/ua/performancelab/MemoryChurnActivity.java b/app/src/main/java/com/performance/ua/performancelab/MemoryChurnActivity.java index d4fef0b..8043927 100644 --- a/app/src/main/java/com/performance/ua/performancelab/MemoryChurnActivity.java +++ b/app/src/main/java/com/performance/ua/performancelab/MemoryChurnActivity.java @@ -50,17 +50,21 @@ public void imPrettySureSortingIsFree() { } // Now go through and dump the sorted version of each row to output! + StringBuilder builder = new StringBuilder(); for (int i = 0; i < lotsOfInts.length; i++) { String rowAsStr = ""; + builder = new StringBuilder(); for (int j = 0; j < lotsOfInts[i].length; j++) { // Clearly, the only reasonable way to construct a string is one character at a // time, with lots and lots of convenient concatenation. - rowAsStr += getSorted(lotsOfInts[i])[j]; +// rowAsStr += getSorted(lotsOfInts[i])[j]; + builder.append(getSorted(lotsOfInts[i])[j]); if (j < (lotsOfInts[i].length - 1)) { - rowAsStr += ", "; +// rowAsStr += ", "; + builder.append(", "); } } - Log.i("MemoryChurnActivity", "Row " + i + ": " + rowAsStr); + Log.i("MemoryChurnActivity", "Row " + i + ": " + builder.toString()); } }