Home > Development > Simulating optimization with threads!

Simulating optimization with threads!

Disclaimer: This is a programming topic. Not that scary though.

As the title says, it is possible to not write well optimized code, but replace it with threads. (VERY simply put, a thread is a program within a program. It runs at the same time another part of the program* runs.)

Is it bad practice or good? I think it depends. For example in previous versions of zkanji I had to store a lot of temporary data during the long-term study, to make it fast to get the next item after answering another. This is a way of optimization, you make extra care that everything works fast. This also added a lot of complexity to the code, and complex code is harder to fix if something works badly. Because of that optimization I was too scared to change the code to allow adding new items to study, after you finished studying previous items for the day.

So how do we replace optimization with threads? If you can make more code to run at the same time, the program will appear to be doing its task faster. (I’m not an expert at this but maybe if you are on a laptop this will also drain its batteries a bit faster.) In our case in zkanji, while you are thinking about the answer to an item, the program can do “stuff”. For example, it can find the next item to show after the current one. Finding the next item is fast while there are not many items to study, so there would be no need to add a thread just for that, but after years and years adding new items, it can have a visible lag after the answer was given and before the new item is shown.

This is probably a very simple example, but as the lag wouldn’t be more than a second on slower computers, I don’t think it’s worth my time optimizing it. And also, you’ll be able to add new items to study any time. I will consider adding new threads for small things like this if they make my life easier and the program simpler, but threads come with their own complexities and difficulties, so avoid them if possible.

*Technically speaking, the “another part of the program” is another thread. Every program has at least one thread, even if it’s only the single main thread.

Categories: Development Tags: , ,
  1. Ricardo
    August 4, 2015 at 2:15 pm

    I think threads make a lot of sense when you want to run a task asynchronously and the gain is very obvious and not achievable in any other way. E.g., in a single thread program, saving a very large file can cause the UI to “hang” since the processing is I/O bound; but as you said, your code becomes more complex (think about handling exceptions, blocking the use of the same file while it is being saved, etc.)…

    But if you are just “reading” data, I believe that creating an index should be much simpler and much faster than using threads. I don’t know how is the structure you have created for the data, but my guess is that your perceived lag is due to seek times, and not transfer times, so an index should reduce the seek time considerably.

    • August 5, 2015 at 12:59 am

      To make zkanji fast I’ve kept everything in memory from the start (except the huge example sentences data). There is no seeking or file reading or anything while you test, just a lot of comparisons and such in many loops when looking for the next item to test in the long-term study.
      In previous versions I solved this with a cleverly ordered list of items but it wasn’t flexible enough for stuff I wanted to add. Keeping the list up to date wasn’t that simple and adding features that change the ordering wasn’t an option.This time I won’t do it that way, instead I’ll find the next item in the simple unsorted list with brute force each time.

      Btw I haven’t tested yet whether this will be slow or not (it’s very much possible for all the loops it does). Putting the search in a separate thread while the user thinks of the answer of the current item adds no complexity whatsoever because there is no race condition. The thread doesn’t have to be careful with the data it accesses and neither the main program.

      • Ricardo
        August 12, 2015 at 3:14 pm

        I’m not sure what you want to do exactly, but my guess is that if you plan to replace complex code that runs in, e.g., O(log n), with a simpler code running in O(n) (or slower), this trade off between code complexity and performance might not be justifiable in the long run, specially for those that are going to use that feature the most. But if you can calculate (or test) the worst case scenario (think ‘big’) and if it is not so bad, why not go for it?

        I personally would prefer more complexity and better performance. And to deal with complex code it helps to split it into different objects / files / libraries, and create some unit tests (see http://doc.qt.io/qt-5/qttest-index.html ).

        I remember writing some “clever” (but not so “maintainable”) code for a Palm Pilot application a few years ago. It would search for sentences in the Tanaka Corpus containing the kanji or word provided by the user. It was pretty fast and used very little power (a limited resource in mobile devices), but the data was static, so it was easy to optimize.

        But if you need to do a lot of searches and some insertions / deletions, why not refactor your code and use (or create) another data structure, such as QHash or QMap? You can see how these and other structures perform here: http://doc.qt.io/qt-5/containers.html#algorithmic-complexity

      • August 12, 2015 at 6:40 pm

        There’s a huge misunderstanding here (apart from assuming that I don’t know what I’m doing.) You are commenting about a general case, though I think I explained the circumstances.

        The reason I didn’t write more complex but a bit faster code was NOT because I couldn’t do it. I simply didn’t care if that part of the code was fast or not. The user is going to at least think for 2-3 seconds before pressing a button or entering an answer. And that’s when the thread runs. Should I spend another 1-2 days optimizing something that they won’t even notice? It’s not worth the time but if you think so, you can do it later. The code will go open-source at the same time the new version is released.

        By the way this part of the code is already done, and at least on my machine neither the thread nor additional optimization seems to even be necessary. I couldn’t use much from the old version and had to rewrite the whole thing. Apparently the new algorithm is simply fast enough.

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: