Aug 21 | 7:20 PM |
Mark M. | has entered the room |
Mark M. | turned on guest access |
Aug 21 | 7:25 PM |
EGHDK | has entered the room |
Mark M. |
hello, EGHDK
|
Aug 21 | 7:30 PM |
EGHDK |
Hey Mark.
|
Mark M. |
first, let me apologize for my harsh tone in yesterday's Stack Overflow discussion
|
EGHDK |
Hahaha. I didn't think it was harsh?
|
Mark M. |
I was in kind of a foul mood at the time
|
EGHDK |
It's alright. I didn't see it as harsh. I just wanted to make sure my question made sense.
|
Mark M. |
OK, good to hear that you didn't take it badly
|
EGHDK |
I hope anything that put you in your foul mood wasn't anything too serious.
|
EGHDK |
And I appreciate the help with it. I will definitely go that route.
|
Mark M. |
what you want is reasonable, but figuring out how "map stuff" translates into screen information, in terms of your zoom level, may be unpleasant
|
Mark M. |
but, anyway -- how can I help you today?
|
EGHDK |
Yeah. It's really tough. I can't figure out a way to make my customer happy while having something that is simple/quick enough. Google maps is just too much for this simple impelmentation of a square block map essentially.
|
EGHDK |
I just need a square block with road names and 4 or 5 building names to load quickly. and Gmapps is too much in my opinion.
|
EGHDK |
Anyway, my question is about threading/speed in android
|
Aug 21 | 7:35 PM |
EGHDK |
Again, mostly dealing with code golf examples I'm reading online, but I'm turning them into something practical. Just for practice really.
|
Mark M. |
just remember: golf spelled backwards is flog
|
EGHDK |
?
|
Mark M. |
just a joke -- nevermind
|
EGHDK |
oh. hahah. Don't get it. =)
|
EGHDK |
Looked up flog..
|
EGHDK |
hahaha
|
EGHDK |
Anyway, you are given a method that takes 500 ms to run. You don't know what it does, but it's computing something or other and it takes 500ms. How can you run that most efficiently 10 times.
|
EGHDK |
So I tried just doing an asynctask with a loop inside. so running it of course takes about 5 seconds.
|
Mark M. |
without more details, that's not really answerable
|
EGHDK |
I started reading online that you can get the number of cores a processor has.
|
EGHDK |
Well the details was that it's a native method. SO I can't tell what it's doing. Besides learning some basic ndk
|
EGHDK |
But I basically have a method that I call and it takes about 500ms.
|
EGHDK |
I started looking into thread pools, and from what I can tell, that's more of what I should look into?
|
Aug 21 | 7:40 PM |
Mark M. |
yes, running threads in parallel will help, in one of two scenarios:
|
EGHDK |
Okay. Yes. I just wanted to pick your brain on it.
|
Mark M. |
1. your mystery code is CPU-bound, in which case running parallel threads can run your code simultaneously on multiple cores
|
Mark M. |
2. your mystery code is I/O-bound, in which case running parallel threads can get work done while other threads are waiting for the I/O to complete
|
EGHDK |
Yeah, so for the first scenario... how would you decide how many parallel threads to run?
|
EGHDK |
Is it worth it to try to get processor info?
|
EGHDK |
And try to calculate the number of parallel threads to run it on?
|
EGHDK |
Assuming a quad core chip meant that 4 parallel threads are possible/optimal?
|
Mark M. |
whether 4 threads are optimal depends on what the mystery method is doing
|
Mark M. |
also, there are environmental factors to take into account
|
Mark M. |
in Android, you don't control how many cores you wind up using
|
Mark M. |
so probably going with 4 threads would be the right answer
|
Mark M. |
just bear in mind that you might not get allocated all four cores
|
Aug 21 | 7:45 PM |
Mark M. |
Runtime.getRuntime().availableProcessors() is the simplest way to get an idea of how many cores exist
|
Mark M. |
though it only really gives an accurate value for Android 4.2+
|
EGHDK |
So I would use that and create that many threads?
|
Mark M. |
yes
|
EGHDK |
Because I'm mostly confused what a thread pool is.
|
Mark M. |
in programming, a "pool" means a collection of some resource
|
Mark M. |
hence, a "thread pool" is a collection of threads
|
Mark M. |
rather than saying "I'm going to fork as many threads as I want to", you bound yourself to some maximum number of threads
|
Mark M. |
having too many threads can cause its own type of performance problem
|
EGHDK |
Yes. Makes sense. So would a thread pool in this case make sense? Or is it the same thing?
|
EGHDK |
Creating threads has a cost... no?
|
EGHDK |
Is that the performance problem you're talking about?
|
Mark M. |
whether or not you put them formally in a pool or not (e.g., use an ExecutorService) would be an implementation detail for your case, but would be more important for other scenarios
|
Mark M. |
with respect to performance, let's say we have 4 cores and 1024 threads
|
Mark M. |
we're going to spend an awful lot of time switching between all those threads, if they are all "ready to run" (i.e., are not blocking waiting for I/O or something to complete)
|
Mark M. |
the overhead of thread "context switching" becomes too high
|
EGHDK |
Yes. Makes sense. 4 cores would mean that 4 threads (1 per core) would be optimal.
|
Mark M. |
if those threads are constantly running
|
Aug 21 | 7:50 PM |
EGHDK |
Yeah.
|
Aug 21 | 7:50 PM |
Mark M. |
if those threads are blocking on I/O, then having more threads would be optimal, but not an insane number
|
Mark M. |
you'll typically see algorithms like "twice the number of cores, plus one"
|
Mark M. |
or variations on that theme
|
Mark M. |
firms with enough engineering time can tweak the size of the thread pool to maximize performance for their app and what their app does
|
EGHDK |
Got it.
|
EGHDK |
So I guess my question is... if you were given a method that you knew wasn't restricted by i/o. Just by cpu. How would you run that method, 10 times as fast as you could (and order didn't matter).
|
EGHDK |
Would you get the number of cores... and just create 4 separate threads?
|
EGHDK |
Or would you create a threadpool/executor that you metntioned?
|
Mark M. |
create Runtime.getRuntime().availableProcessors() number of threads, in a thread pool, working off of a 10 element work queue
|
Mark M. |
the catch with threading is that you never quite know which threads will wrap up first
|
Mark M. |
particularly with multi-core CPUs
|
Mark M. |
and, on Android, you don't control how many cores you get anyway
|
Mark M. |
so, you use the number of threads that in theory will use all possible cores
|
EGHDK |
Great. So you would use a threadPoolExecutor object?
|
Mark M. |
yup
|
EGHDK |
Great.
|
Aug 21 | 7:55 PM |
EGHDK |
Because I was getting the available processors, but I was creating 4 threads in a for loop... and in each threads runnable I told it to run 2 times. And that was where I got stuck.
|
Mark M. |
the overhead of the work queue will be swamped by the 500ms time for the work
|
Mark M. |
hence, using ThreadPoolExecutor and a 10-element work queue will simplify your life
|
EGHDK |
So since I'm looking at the ThreadPoolExecutor android docs... which constructor would you use?
|
EGHDK |
Like... do I need a ThreadFactory?
|
Mark M. |
probably not
|
Mark M. |
if you're looking at the Android docs, I'd go with the first one
|
EGHDK |
Okay, that's what I thought.
|
Mark M. |
the five-parameter one, without the ThreadFactory or RejectedExecutionHandler
|
Mark M. |
as in your case, you won't need either of those
|
EGHDK |
(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue)
|
Mark M. |
yup
|
EGHDK |
So what would go in each of those. Mainly core and max pool size?
|
EGHDK |
Would I make both the same int?
|
Mark M. |
your core pool size would be your number of processors
|
Aug 21 | 8:00 PM |
Mark M. |
your max pool size would also be your number of processors -- you just aren't taking advantage of ThreadPoolExecutor's flexibility in adding/removing threads, that's all
|
Mark M. |
keepAliveTime and its units won't much matter, as they only come into play if max pool size > core pool size
|
Mark M. |
so, I'd go with 0 seconds
|
Mark M. |
and LinkedBlockingQueue is a likely implementation of the BlockingQueue interface
|
EGHDK |
Okay. So keeping them at the same number would be smart in this case. But if I made the core and max vary, then the threadpool has flexibility?
|
Mark M. |
yes
|
Mark M. |
you'll start off with the core # of threads
|
EGHDK |
Got it. So why wouldn't I do it here?
|
Mark M. |
and, if you keep shoving more work into the queue, the pool can grow to the max number of threads
|
Mark M. |
because you know you want N threads (N = # cores)
|
Mark M. |
you may as well set them up at the outset
|
EGHDK |
gotcha. Okay.
|
EGHDK |
View paste
|
EGHDK |
so we just discussed scenario 1.
|
EGHDK |
so scenario 2 is just basic android "take this off the main thread" stuff... right?
|
EGHDK |
Like db and network, not on the main thread.
|
EGHDK |
That would technically be running parralel threads?
|
Mark M. |
sure
|
Mark M. |
how truly parallel they are depends on the number of cores and such
|
EGHDK |
Okay, because the parallel thread terminology got me nervous.
|
EGHDK |
Oh okay.
|
Aug 21 | 8:05 PM |
EGHDK |
So wait. In java when I saw create a new thread... will it always be on the same core? Or will it put it onto another?
|
Aug 21 | 8:05 PM |
Mark M. |
that's up to the OS
|
EGHDK |
Or it's up to the OS/VM to decide?
|
Mark M. |
and in Android, we as SDK developers get no control or visibility over the matter
|
Mark M. |
IOW, "it is what it is"
|
EGHDK |
Okay great.
|
EGHDK |
Best thing to do is to probably test and benchmark.
|
EGHDK |
and not only one device either =)
|
Mark M. |
yes
|
EGHDK |
Okay. So generally speaking, getting the number of cores and creating a threadPoolExecutor of that size should do a better job, than just 1 thread.
|
Mark M. |
yes
|
EGHDK |
So at first I was making multiple asyncTasks. I have a felling thats bad...
|
EGHDK |
but why?
|
EGHDK |
I know asynctask implementation has changed over the years in android
|
Mark M. |
it's not necessarily "bad"
|
Mark M. |
under the covers, AsyncTask uses ThreadPoolExecutor
|
Mark M. |
however, its pool is not tuned for your code golf scenario
|
Mark M. |
and it has overhead for messing with all the "communicate back to the main application thread" stuff that you don't need
|
EGHDK |
Gotcha.
|
EGHDK |
Got it.
|
EGHDK |
Thanks. Very helpful.
|
Aug 21 | 8:10 PM |
EGHDK |
Any other basic threading info you think I should know about?
|
Mark M. |
get yourself a copy of _Java Concurrency in Practice_
|
EGHDK |
I know theres book on it. I bought java concurrency in action (that should be about threads right?) because I got a lot of people recomending it. SO I'm slowly making my way... heh
|
EGHDK |
hahaha
|
EGHDK |
Figures!
|
EGHDK |
I own it. Just reading through some other text first.
|
Mark M. |
now, bear in mind that this book is for general Java
|
Mark M. |
it won't have any Android-isms
|
EGHDK |
The book by josh bloch (i think) can't remember the name is a little intimidating. Theres somethings I don't understand.
|
Mark M. |
IIRC, his is a bit older
|
Mark M. |
but his original concurrency classes formed the foundation for java.util.concurrent
|
EGHDK |
But I'm still gaining a lot.
|
Mark M. |
and things like ThreadPoolExecutor
|
EGHDK |
Yeah. Right now working with threads and collections api is tricky.
|
EGHDK |
A lot of interviews ask for specifics with collection api and I just don't know enough.
|
EGHDK |
Theres SO MUCH OF IT.
|
Mark M. |
yes
|
Aug 21 | 8:15 PM |
EGHDK |
You don't know all of collections off the top of your head right? Haha. The last interview they asked me to take a file and see how many unique ip addresses visited a site. They gave me a .txt and asked me how I would do it.
|
EGHDK |
I first said array
|
EGHDK |
they said no because of memory limitations
|
EGHDK |
I then said DB, and they said that's too big for what we're doing.
|
Mark M. |
HashSet
|
EGHDK |
And I was stumped.
|
EGHDK |
Yeah... they said hashmap
|
EGHDK |
=\ So disappointing.
|
EGHDK |
Because apparently it doesn't accept duplicates?
|
Mark M. |
correct
|
EGHDK |
But I didn't get it. Why did they not say yes to an array?
|
Mark M. |
because an array can have duplicates
|
Mark M. |
suppose the text file has 10,000 lines, with only 2 unique IP addresses
|
EGHDK |
This is true.
|
Mark M. |
you may want to read up on quintessential data structures, like sets
|
Mark M. |
there are implementations of things like that in most programming languages
|
EGHDK |
ANy books for that? I'll bump that up on my reading list.
|
EGHDK |
Really? SO its not just java?
|
EGHDK |
I guess that makes sense.
|
Aug 21 | 8:20 PM |
EGHDK |
I really only deal with java, but I'm sure theres a lot of overlap with other langs.
|
Mark M. |
I learned those things back when our tablets were made of stone
|
Mark M. |
so I don't have a great reference off the top of my head
|
EGHDK |
hahaha
|
EGHDK |
Urg. Alright.
|
Mark M. |
I'd start with the Wikipedia article for "set" and explore from there
|
EGHDK |
So what should I "search" on google or amazon?
|
EGHDK |
Okay, I guess wiki it is!
|
Mark M. | |
Mark M. |
which leads to http://en.wikipedia.org/wiki/Abstract_data_stru...
|
Mark M. |
the latter is rather obtuse, but it's a starting point
|
EGHDK |
Head first java touched on them briefly, but I was like this is insane!
|
Mark M. |
the Examples section on that second page, though, is good
|
EGHDK |
There is some sort of collection for everything
|
EGHDK |
And then they said the hashmaps (or hashset? I don't know what the parent) aren't even technically in Collections api. haha
|
Mark M. |
HashSet and HashMap are both in java.util
|
EGHDK |
Oh.
|
EGHDK |
Interesting.
|
Mark M. |
I haven't heard somebody refer to that as "the Collections API" in a decade or so
|
Aug 21 | 8:25 PM |
EGHDK |
Yeah. I mean head first java said that they wanted to clear up when they said Collections and collections. That a hashset is a collection but its not in collections.
|
Mark M. |
they may be referring to the class java.util.Collections
|
Mark M. |
I don't exactly see why they cared about that in the context of the interview question
|
EGHDK |
Yeah. Well to start off they asked me if I knew the big O.
|
EGHDK |
ANd I was like...
|
EGHDK |
*cricket* *cricket*
|
Mark M. |
while I know what they mean by "big-O", if they're asking about that in an interview with me, they failed the interview
|
Mark M. |
not that I've been on an interview in 14 years, mind you
|
EGHDK |
Hahah. Can you elaborate on "they failed the interview"?
|
Mark M. |
that's a bit beyond what I'd like to cover in a chat
|
EGHDK |
ALright. Well its time to call it a night
|
EGHDK |
Thanks again.
|
Mark M. |
you're very welcome
|
Aug 21 | 8:30 PM |
Mark M. |
the next office hours are Tuesday at 9am US Eastern Time
|
EGHDK |
WIsh we just had professors like you instead of the crap that we get usually.
|
EGHDK |
Will be there. With questions. Hahah. GOodnight!
|
Mark M. |
have a pleasant evening!
|
EGHDK | has left the room |
Mark M. | turned off guest access |