Threading vs Normal in Python












0















import time
import threading
import multiprocessing

def fn():
'''since all 3 functions were identical you can just use one ...'''
x = 0
while x < 100000000:
x += 1




def TEST_THREADS():
new_thread1 = threading.Thread(target = fn , args = ())
new_thread2 = threading.Thread(target = fn, args = ())
new_thread1.start()
new_thread2.start()
new_thread1.join()
new_thread2.join()

def TEST_NORMAL():
fn()
fn()

def TEST_MULTIPROCESSING():
new_thread1 = multiprocessing.Process(target = fn , args = ())
new_thread2 = multiprocessing.Process(target = fn, args = ())
new_thread1.start()
new_thread2.start()
new_thread1.join()
new_thread2.join()
if __name__ == "__main__":
'''It is very important to use name == __main__ guard code with threads and multiprocessing'''
import timeit
print ("Time to Run 1x: %0.2fs"%(timeit.timeit(fn,number=1),))
print ("NORMAL:%0.2fs"%(timeit.timeit(TEST_NORMAL,number=1),))
print ("Threaded: %0.2fs"%(timeit.timeit(TEST_THREADS,number=1),))
print ("Multiprocessing: %0.2fs"% (timeit.timeit(TEST_MULTIPROCESSING,number=1),))


I found interesting presentetion about GIL and Threading:
http://www.dabeaz.com/python/NewGIL.pdf
So I wrote similar code, but get strange results:



Time to Run 1x: 11.60s
NORMAL:23.15s
Threaded: 23.43s
Multiprocessing: 1.19s


As you can see, threading method ran faster than normal one or equally (0.28s not too much).
I found some articles and similar questions, but everywhere results were like in presentetion- threading is slower.



Am I doing something wrong or new Python version improved GIL?



However, Multiprocessing also went crazy and work 20x faster than others! Is it ok?










share|improve this question




















  • 1





    it's the same time plus the overhead of creating & managing the thread. If you know the GIL why does the result surprise you?

    – Jean-François Fabre
    Nov 25 '18 at 20:06






  • 1





    multiprocessing runs 20x faster than the non-threaded version. Doesn't that surprise you more?

    – Jean-François Fabre
    Nov 25 '18 at 20:08











  • Everywhere threads are much slower. Sequential : 24.6s Threaded : 45.5s or something like that

    – V.k.n.s
    Nov 25 '18 at 20:14








  • 1





    the timings in your question are different. You state 0.28s difference, and your comment states 200% increase. Which one is it?

    – Jean-François Fabre
    Nov 25 '18 at 20:19











  • The GIL doesn't apply when you create a whole new process in multiprocessing, which is why you see the 20x increase. Even this is a bit surprising, because I'm guessing you'd expect only a 2x increase at most. As for the slight difference in time between MT and ST, that seems too insignificant to draw any meaningful conclusions from.

    – ggorlen
    Nov 25 '18 at 20:26
















0















import time
import threading
import multiprocessing

def fn():
'''since all 3 functions were identical you can just use one ...'''
x = 0
while x < 100000000:
x += 1




def TEST_THREADS():
new_thread1 = threading.Thread(target = fn , args = ())
new_thread2 = threading.Thread(target = fn, args = ())
new_thread1.start()
new_thread2.start()
new_thread1.join()
new_thread2.join()

def TEST_NORMAL():
fn()
fn()

def TEST_MULTIPROCESSING():
new_thread1 = multiprocessing.Process(target = fn , args = ())
new_thread2 = multiprocessing.Process(target = fn, args = ())
new_thread1.start()
new_thread2.start()
new_thread1.join()
new_thread2.join()
if __name__ == "__main__":
'''It is very important to use name == __main__ guard code with threads and multiprocessing'''
import timeit
print ("Time to Run 1x: %0.2fs"%(timeit.timeit(fn,number=1),))
print ("NORMAL:%0.2fs"%(timeit.timeit(TEST_NORMAL,number=1),))
print ("Threaded: %0.2fs"%(timeit.timeit(TEST_THREADS,number=1),))
print ("Multiprocessing: %0.2fs"% (timeit.timeit(TEST_MULTIPROCESSING,number=1),))


I found interesting presentetion about GIL and Threading:
http://www.dabeaz.com/python/NewGIL.pdf
So I wrote similar code, but get strange results:



Time to Run 1x: 11.60s
NORMAL:23.15s
Threaded: 23.43s
Multiprocessing: 1.19s


As you can see, threading method ran faster than normal one or equally (0.28s not too much).
I found some articles and similar questions, but everywhere results were like in presentetion- threading is slower.



Am I doing something wrong or new Python version improved GIL?



However, Multiprocessing also went crazy and work 20x faster than others! Is it ok?










share|improve this question




















  • 1





    it's the same time plus the overhead of creating & managing the thread. If you know the GIL why does the result surprise you?

    – Jean-François Fabre
    Nov 25 '18 at 20:06






  • 1





    multiprocessing runs 20x faster than the non-threaded version. Doesn't that surprise you more?

    – Jean-François Fabre
    Nov 25 '18 at 20:08











  • Everywhere threads are much slower. Sequential : 24.6s Threaded : 45.5s or something like that

    – V.k.n.s
    Nov 25 '18 at 20:14








  • 1





    the timings in your question are different. You state 0.28s difference, and your comment states 200% increase. Which one is it?

    – Jean-François Fabre
    Nov 25 '18 at 20:19











  • The GIL doesn't apply when you create a whole new process in multiprocessing, which is why you see the 20x increase. Even this is a bit surprising, because I'm guessing you'd expect only a 2x increase at most. As for the slight difference in time between MT and ST, that seems too insignificant to draw any meaningful conclusions from.

    – ggorlen
    Nov 25 '18 at 20:26














0












0








0








import time
import threading
import multiprocessing

def fn():
'''since all 3 functions were identical you can just use one ...'''
x = 0
while x < 100000000:
x += 1




def TEST_THREADS():
new_thread1 = threading.Thread(target = fn , args = ())
new_thread2 = threading.Thread(target = fn, args = ())
new_thread1.start()
new_thread2.start()
new_thread1.join()
new_thread2.join()

def TEST_NORMAL():
fn()
fn()

def TEST_MULTIPROCESSING():
new_thread1 = multiprocessing.Process(target = fn , args = ())
new_thread2 = multiprocessing.Process(target = fn, args = ())
new_thread1.start()
new_thread2.start()
new_thread1.join()
new_thread2.join()
if __name__ == "__main__":
'''It is very important to use name == __main__ guard code with threads and multiprocessing'''
import timeit
print ("Time to Run 1x: %0.2fs"%(timeit.timeit(fn,number=1),))
print ("NORMAL:%0.2fs"%(timeit.timeit(TEST_NORMAL,number=1),))
print ("Threaded: %0.2fs"%(timeit.timeit(TEST_THREADS,number=1),))
print ("Multiprocessing: %0.2fs"% (timeit.timeit(TEST_MULTIPROCESSING,number=1),))


I found interesting presentetion about GIL and Threading:
http://www.dabeaz.com/python/NewGIL.pdf
So I wrote similar code, but get strange results:



Time to Run 1x: 11.60s
NORMAL:23.15s
Threaded: 23.43s
Multiprocessing: 1.19s


As you can see, threading method ran faster than normal one or equally (0.28s not too much).
I found some articles and similar questions, but everywhere results were like in presentetion- threading is slower.



Am I doing something wrong or new Python version improved GIL?



However, Multiprocessing also went crazy and work 20x faster than others! Is it ok?










share|improve this question
















import time
import threading
import multiprocessing

def fn():
'''since all 3 functions were identical you can just use one ...'''
x = 0
while x < 100000000:
x += 1




def TEST_THREADS():
new_thread1 = threading.Thread(target = fn , args = ())
new_thread2 = threading.Thread(target = fn, args = ())
new_thread1.start()
new_thread2.start()
new_thread1.join()
new_thread2.join()

def TEST_NORMAL():
fn()
fn()

def TEST_MULTIPROCESSING():
new_thread1 = multiprocessing.Process(target = fn , args = ())
new_thread2 = multiprocessing.Process(target = fn, args = ())
new_thread1.start()
new_thread2.start()
new_thread1.join()
new_thread2.join()
if __name__ == "__main__":
'''It is very important to use name == __main__ guard code with threads and multiprocessing'''
import timeit
print ("Time to Run 1x: %0.2fs"%(timeit.timeit(fn,number=1),))
print ("NORMAL:%0.2fs"%(timeit.timeit(TEST_NORMAL,number=1),))
print ("Threaded: %0.2fs"%(timeit.timeit(TEST_THREADS,number=1),))
print ("Multiprocessing: %0.2fs"% (timeit.timeit(TEST_MULTIPROCESSING,number=1),))


I found interesting presentetion about GIL and Threading:
http://www.dabeaz.com/python/NewGIL.pdf
So I wrote similar code, but get strange results:



Time to Run 1x: 11.60s
NORMAL:23.15s
Threaded: 23.43s
Multiprocessing: 1.19s


As you can see, threading method ran faster than normal one or equally (0.28s not too much).
I found some articles and similar questions, but everywhere results were like in presentetion- threading is slower.



Am I doing something wrong or new Python version improved GIL?



However, Multiprocessing also went crazy and work 20x faster than others! Is it ok?







python multithreading time gil






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 25 '18 at 20:40







V.k.n.s

















asked Nov 25 '18 at 20:02









V.k.n.sV.k.n.s

43




43








  • 1





    it's the same time plus the overhead of creating & managing the thread. If you know the GIL why does the result surprise you?

    – Jean-François Fabre
    Nov 25 '18 at 20:06






  • 1





    multiprocessing runs 20x faster than the non-threaded version. Doesn't that surprise you more?

    – Jean-François Fabre
    Nov 25 '18 at 20:08











  • Everywhere threads are much slower. Sequential : 24.6s Threaded : 45.5s or something like that

    – V.k.n.s
    Nov 25 '18 at 20:14








  • 1





    the timings in your question are different. You state 0.28s difference, and your comment states 200% increase. Which one is it?

    – Jean-François Fabre
    Nov 25 '18 at 20:19











  • The GIL doesn't apply when you create a whole new process in multiprocessing, which is why you see the 20x increase. Even this is a bit surprising, because I'm guessing you'd expect only a 2x increase at most. As for the slight difference in time between MT and ST, that seems too insignificant to draw any meaningful conclusions from.

    – ggorlen
    Nov 25 '18 at 20:26














  • 1





    it's the same time plus the overhead of creating & managing the thread. If you know the GIL why does the result surprise you?

    – Jean-François Fabre
    Nov 25 '18 at 20:06






  • 1





    multiprocessing runs 20x faster than the non-threaded version. Doesn't that surprise you more?

    – Jean-François Fabre
    Nov 25 '18 at 20:08











  • Everywhere threads are much slower. Sequential : 24.6s Threaded : 45.5s or something like that

    – V.k.n.s
    Nov 25 '18 at 20:14








  • 1





    the timings in your question are different. You state 0.28s difference, and your comment states 200% increase. Which one is it?

    – Jean-François Fabre
    Nov 25 '18 at 20:19











  • The GIL doesn't apply when you create a whole new process in multiprocessing, which is why you see the 20x increase. Even this is a bit surprising, because I'm guessing you'd expect only a 2x increase at most. As for the slight difference in time between MT and ST, that seems too insignificant to draw any meaningful conclusions from.

    – ggorlen
    Nov 25 '18 at 20:26








1




1





it's the same time plus the overhead of creating & managing the thread. If you know the GIL why does the result surprise you?

– Jean-François Fabre
Nov 25 '18 at 20:06





it's the same time plus the overhead of creating & managing the thread. If you know the GIL why does the result surprise you?

– Jean-François Fabre
Nov 25 '18 at 20:06




1




1





multiprocessing runs 20x faster than the non-threaded version. Doesn't that surprise you more?

– Jean-François Fabre
Nov 25 '18 at 20:08





multiprocessing runs 20x faster than the non-threaded version. Doesn't that surprise you more?

– Jean-François Fabre
Nov 25 '18 at 20:08













Everywhere threads are much slower. Sequential : 24.6s Threaded : 45.5s or something like that

– V.k.n.s
Nov 25 '18 at 20:14







Everywhere threads are much slower. Sequential : 24.6s Threaded : 45.5s or something like that

– V.k.n.s
Nov 25 '18 at 20:14






1




1





the timings in your question are different. You state 0.28s difference, and your comment states 200% increase. Which one is it?

– Jean-François Fabre
Nov 25 '18 at 20:19





the timings in your question are different. You state 0.28s difference, and your comment states 200% increase. Which one is it?

– Jean-François Fabre
Nov 25 '18 at 20:19













The GIL doesn't apply when you create a whole new process in multiprocessing, which is why you see the 20x increase. Even this is a bit surprising, because I'm guessing you'd expect only a 2x increase at most. As for the slight difference in time between MT and ST, that seems too insignificant to draw any meaningful conclusions from.

– ggorlen
Nov 25 '18 at 20:26





The GIL doesn't apply when you create a whole new process in multiprocessing, which is why you see the 20x increase. Even this is a bit surprising, because I'm guessing you'd expect only a 2x increase at most. As for the slight difference in time between MT and ST, that seems too insignificant to draw any meaningful conclusions from.

– ggorlen
Nov 25 '18 at 20:26












1 Answer
1






active

oldest

votes


















1














In modern Python, the GIL isn't as bad as it used to be (previously, you could expect CPU bound threaded code to run meaningfully slower), so your observation is roughly what you'd expect.



From personal experience, a bunch of CPU bound threads on CPython 2.7 could use close to two cores of CPU, and accomplish less than 75% of a core's worth of work. Since they rewrote the GIL in CPython 3.2, that overhead largely disappeared; you still don't gain anything from the threading, but you end up using 1-1.1 cores' worth of compute and accomplish 95-100% of a core's worth of work. Basically, the GIL doesn't meaningfully slow code anymore, but it still prevents you from reaping a benefit from threading with CPU bound code that isn't based on third party GIL-releasing extensions like numpy.






share|improve this answer
























  • Thank you so much. However, can you explain 20x increase in multiprocessing? I'm puzzled about such gain.

    – V.k.n.s
    Nov 25 '18 at 20:41













  • @V.k.n.s: The number seems unbelievable at first glance. I can't explain it from the code you posted. Running it myself (on CPython x64 3.7.1 on Ubuntu on Windows), I get ~4.5 s for single run, ~9 s each for NORMAL and Threaded, and ~6 s for Multiprocessing, which all seems reasonable. You'd have to give a lot more details on Python version and OS to even have a chance of guessing. My assumption would be that you're using a non-default timer that measures CPU time, not wall clock time, so the CPU time in the worker processes wouldn't be counted, but that's a guess not supported by your code.

    – ShadowRanger
    Nov 25 '18 at 21:00













Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53471390%2fthreading-vs-normal-in-python%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














In modern Python, the GIL isn't as bad as it used to be (previously, you could expect CPU bound threaded code to run meaningfully slower), so your observation is roughly what you'd expect.



From personal experience, a bunch of CPU bound threads on CPython 2.7 could use close to two cores of CPU, and accomplish less than 75% of a core's worth of work. Since they rewrote the GIL in CPython 3.2, that overhead largely disappeared; you still don't gain anything from the threading, but you end up using 1-1.1 cores' worth of compute and accomplish 95-100% of a core's worth of work. Basically, the GIL doesn't meaningfully slow code anymore, but it still prevents you from reaping a benefit from threading with CPU bound code that isn't based on third party GIL-releasing extensions like numpy.






share|improve this answer
























  • Thank you so much. However, can you explain 20x increase in multiprocessing? I'm puzzled about such gain.

    – V.k.n.s
    Nov 25 '18 at 20:41













  • @V.k.n.s: The number seems unbelievable at first glance. I can't explain it from the code you posted. Running it myself (on CPython x64 3.7.1 on Ubuntu on Windows), I get ~4.5 s for single run, ~9 s each for NORMAL and Threaded, and ~6 s for Multiprocessing, which all seems reasonable. You'd have to give a lot more details on Python version and OS to even have a chance of guessing. My assumption would be that you're using a non-default timer that measures CPU time, not wall clock time, so the CPU time in the worker processes wouldn't be counted, but that's a guess not supported by your code.

    – ShadowRanger
    Nov 25 '18 at 21:00


















1














In modern Python, the GIL isn't as bad as it used to be (previously, you could expect CPU bound threaded code to run meaningfully slower), so your observation is roughly what you'd expect.



From personal experience, a bunch of CPU bound threads on CPython 2.7 could use close to two cores of CPU, and accomplish less than 75% of a core's worth of work. Since they rewrote the GIL in CPython 3.2, that overhead largely disappeared; you still don't gain anything from the threading, but you end up using 1-1.1 cores' worth of compute and accomplish 95-100% of a core's worth of work. Basically, the GIL doesn't meaningfully slow code anymore, but it still prevents you from reaping a benefit from threading with CPU bound code that isn't based on third party GIL-releasing extensions like numpy.






share|improve this answer
























  • Thank you so much. However, can you explain 20x increase in multiprocessing? I'm puzzled about such gain.

    – V.k.n.s
    Nov 25 '18 at 20:41













  • @V.k.n.s: The number seems unbelievable at first glance. I can't explain it from the code you posted. Running it myself (on CPython x64 3.7.1 on Ubuntu on Windows), I get ~4.5 s for single run, ~9 s each for NORMAL and Threaded, and ~6 s for Multiprocessing, which all seems reasonable. You'd have to give a lot more details on Python version and OS to even have a chance of guessing. My assumption would be that you're using a non-default timer that measures CPU time, not wall clock time, so the CPU time in the worker processes wouldn't be counted, but that's a guess not supported by your code.

    – ShadowRanger
    Nov 25 '18 at 21:00
















1












1








1







In modern Python, the GIL isn't as bad as it used to be (previously, you could expect CPU bound threaded code to run meaningfully slower), so your observation is roughly what you'd expect.



From personal experience, a bunch of CPU bound threads on CPython 2.7 could use close to two cores of CPU, and accomplish less than 75% of a core's worth of work. Since they rewrote the GIL in CPython 3.2, that overhead largely disappeared; you still don't gain anything from the threading, but you end up using 1-1.1 cores' worth of compute and accomplish 95-100% of a core's worth of work. Basically, the GIL doesn't meaningfully slow code anymore, but it still prevents you from reaping a benefit from threading with CPU bound code that isn't based on third party GIL-releasing extensions like numpy.






share|improve this answer













In modern Python, the GIL isn't as bad as it used to be (previously, you could expect CPU bound threaded code to run meaningfully slower), so your observation is roughly what you'd expect.



From personal experience, a bunch of CPU bound threads on CPython 2.7 could use close to two cores of CPU, and accomplish less than 75% of a core's worth of work. Since they rewrote the GIL in CPython 3.2, that overhead largely disappeared; you still don't gain anything from the threading, but you end up using 1-1.1 cores' worth of compute and accomplish 95-100% of a core's worth of work. Basically, the GIL doesn't meaningfully slow code anymore, but it still prevents you from reaping a benefit from threading with CPU bound code that isn't based on third party GIL-releasing extensions like numpy.







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 25 '18 at 20:18









ShadowRangerShadowRanger

62.6k56099




62.6k56099













  • Thank you so much. However, can you explain 20x increase in multiprocessing? I'm puzzled about such gain.

    – V.k.n.s
    Nov 25 '18 at 20:41













  • @V.k.n.s: The number seems unbelievable at first glance. I can't explain it from the code you posted. Running it myself (on CPython x64 3.7.1 on Ubuntu on Windows), I get ~4.5 s for single run, ~9 s each for NORMAL and Threaded, and ~6 s for Multiprocessing, which all seems reasonable. You'd have to give a lot more details on Python version and OS to even have a chance of guessing. My assumption would be that you're using a non-default timer that measures CPU time, not wall clock time, so the CPU time in the worker processes wouldn't be counted, but that's a guess not supported by your code.

    – ShadowRanger
    Nov 25 '18 at 21:00





















  • Thank you so much. However, can you explain 20x increase in multiprocessing? I'm puzzled about such gain.

    – V.k.n.s
    Nov 25 '18 at 20:41













  • @V.k.n.s: The number seems unbelievable at first glance. I can't explain it from the code you posted. Running it myself (on CPython x64 3.7.1 on Ubuntu on Windows), I get ~4.5 s for single run, ~9 s each for NORMAL and Threaded, and ~6 s for Multiprocessing, which all seems reasonable. You'd have to give a lot more details on Python version and OS to even have a chance of guessing. My assumption would be that you're using a non-default timer that measures CPU time, not wall clock time, so the CPU time in the worker processes wouldn't be counted, but that's a guess not supported by your code.

    – ShadowRanger
    Nov 25 '18 at 21:00



















Thank you so much. However, can you explain 20x increase in multiprocessing? I'm puzzled about such gain.

– V.k.n.s
Nov 25 '18 at 20:41







Thank you so much. However, can you explain 20x increase in multiprocessing? I'm puzzled about such gain.

– V.k.n.s
Nov 25 '18 at 20:41















@V.k.n.s: The number seems unbelievable at first glance. I can't explain it from the code you posted. Running it myself (on CPython x64 3.7.1 on Ubuntu on Windows), I get ~4.5 s for single run, ~9 s each for NORMAL and Threaded, and ~6 s for Multiprocessing, which all seems reasonable. You'd have to give a lot more details on Python version and OS to even have a chance of guessing. My assumption would be that you're using a non-default timer that measures CPU time, not wall clock time, so the CPU time in the worker processes wouldn't be counted, but that's a guess not supported by your code.

– ShadowRanger
Nov 25 '18 at 21:00







@V.k.n.s: The number seems unbelievable at first glance. I can't explain it from the code you posted. Running it myself (on CPython x64 3.7.1 on Ubuntu on Windows), I get ~4.5 s for single run, ~9 s each for NORMAL and Threaded, and ~6 s for Multiprocessing, which all seems reasonable. You'd have to give a lot more details on Python version and OS to even have a chance of guessing. My assumption would be that you're using a non-default timer that measures CPU time, not wall clock time, so the CPU time in the worker processes wouldn't be counted, but that's a guess not supported by your code.

– ShadowRanger
Nov 25 '18 at 21:00






















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53471390%2fthreading-vs-normal-in-python%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Tonle Sap (See)

I get strange results when I access the Sqlitedatabase with Unity C# via XAMPP

Guatemaltekische Davis-Cup-Mannschaft