Created
July 4, 2021 13:37
-
-
Save worldOneo/f58d32a67873a7732b624ac235534972 to your computer and use it in GitHub Desktop.
Python performance test with C++ integration
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import mymodule | |
| import random | |
| import time | |
| """ | |
| This is a test for the usecase of C++ integration in python programms. | |
| For small function calls python doesn't gain as much from C++. | |
| But if you keep your entire load in the C++ side, like NumPy, it is much faster. | |
| """ | |
| def random_string_generator(str_size, allowed_chars): | |
| return ''.join(random.choice(allowed_chars) for x in range(str_size)) | |
| def random_int(): | |
| return random.randint(0, 500000) | |
| def random_dict(): | |
| fields = [random_string_generator(20, "abcdefghijklmnopqrstuvwxyz") for _ in range(3_000_000)] | |
| ret = {} | |
| for field in fields: | |
| ret[field] = str(random_int()) | |
| return ret, fields | |
| def translate_with_py(d: dict, i): | |
| for f in i: | |
| if f not in d: | |
| continue | |
| d[f] = int(d[f]) | |
| def timeFunc(title, func): | |
| _t1 = time.time() | |
| res = func() | |
| _t2 = time.time() | |
| print(f"{title} took {round(_t2-_t1, 4)}s") | |
| return res | |
| if __name__ == "__main__": | |
| print("\n=======\nFull C++\n=======") | |
| t1 = time.time() | |
| d, f = timeFunc("Generating challenge for C++ (in C++)", mymodule.generate_dict) | |
| timeFunc("Translating dict in C++ ", lambda: mymodule.translate_dict(d, f)) | |
| t2 = time.time() | |
| fcpp = t2-t1 | |
| print(f"Full C++ took {round(fcpp, 4)}s") | |
| print("\n=======\nPartial C++ (Py Gen)\n=======") | |
| t1 = time.time() | |
| d, f = timeFunc("Generating challenge for C++ (in Py)", random_dict) | |
| timeFunc("Translating dict in C++", lambda: mymodule.translate_dict(d, f)) | |
| t2 = time.time() | |
| pcpppg = t2-t1 | |
| print(f"Partial C++ (PyGen) took {round(pcpppg, 4)}s") | |
| print("\n=======\nPartial C++ (Py Calc)\n=======") | |
| t1 = time.time() | |
| d, f = timeFunc("Generating challenge for Py (in C++)", mymodule.generate_dict) | |
| timeFunc("Translating dict in Py", lambda: translate_with_py(d, f)) | |
| t2 = time.time() | |
| pcpppc = t2-t1 | |
| print(f"Partial C++ (PyCalc) took {round(pcpppc, 4)}s") | |
| print("\n=======\nFull py\n=======") | |
| print() | |
| t1 = time.time() | |
| d, f = timeFunc("Generating challenge for Py (in Py)", random_dict) | |
| timeFunc("Translating dict in Py", lambda: translate_with_py(d, f)) | |
| t2 = time.time() | |
| pytime = t2-t1 | |
| print(f"Python took {round(pytime, 4)}s\n") | |
| print(f"Full C++ is {round(pytime/fcpp*100 - 100, 3)}% faster") | |
| print(f"Partial C++ (PyGen) is {round(pytime/pcpppg*100 - 100, 3)}% faster") | |
| print(f"Partial C++ (PyCalc) is {round(pytime/pcpppc*100 - 100, 3)}% faster") | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <boost/python.hpp> | |
| #include "boost/python/stl_iterator.hpp" | |
| #include <string.h> | |
| #include <vector> | |
| #include <list> | |
| #include <random> | |
| #include <iostream> | |
| using namespace boost; | |
| std::string hello(int test) | |
| { | |
| return std::to_string(test); | |
| } | |
| void translate(python::dict from, python::list intFields) | |
| { | |
| python::stl_input_iterator<std::string> begin(intFields), end; | |
| auto iter = std::list<std::string>(begin, end); | |
| for (std::string field : iter) | |
| { | |
| if (!from.contains(field)) | |
| continue; | |
| int n = atoi(python::extract<const char *>(from[field])); | |
| from[field] = n; | |
| } | |
| } | |
| int random_number() | |
| { | |
| return rand() % 500000; | |
| } | |
| std::string random_string(int n) | |
| { | |
| char letters[] = "abcdefghijklmnopqrstuvwxyz"; | |
| char *ran = (char *)malloc(n); | |
| for (int i = 0; i < n; i++) | |
| ran[i] = letters[rand() % n]; | |
| std::string str = std::string(ran); | |
| free(ran); | |
| return str; | |
| } | |
| python::tuple generate_dict() | |
| { | |
| python::dict res; | |
| python::list fields; | |
| for (int i = 0; i < 3000000; i++) | |
| fields.append(random_string(20)); | |
| python::stl_input_iterator<std::string> begin(fields), end; | |
| auto iter = std::list<std::string>(begin, end); | |
| for (auto key : iter) | |
| res[key] = std::to_string(random_number()); | |
| return python::make_tuple(res, fields); | |
| } | |
| BOOST_PYTHON_MODULE(mymodule) | |
| { | |
| python::def("hello", &hello); | |
| python::def("translate_dict", &translate); | |
| python::def("generate_dict", &generate_dict); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| ======= | |
| Full C++ | |
| ======= | |
| Generating challenge for C++ (in C++) took 2.7518s | |
| Translating dict in C++ took 2.1045s | |
| Full C++ took 4.8564s | |
| ======= | |
| Partial C++ (Py Gen) | |
| ======= | |
| Generating challenge for C++ (in Py) took 24.9276s | |
| Translating dict in C++ took 2.3882s | |
| Partial C++ (PyGen) took 27.4289s | |
| ======= | |
| Partial C++ (Py Calc) | |
| ======= | |
| Generating challenge for Py (in C++) took 2.6688s | |
| Translating dict in Py took 1.2791s | |
| Partial C++ (PyCalc) took 4.1501s | |
| ======= | |
| Full py | |
| ======= | |
| Generating challenge for Py (in Py) took 24.4169s | |
| Translating dict in Py took 0.968s | |
| Python took 25.4773s | |
| Full C++ is 424.609% faster | |
| Partial C++ (PyGen) is -7.115% faster | |
| Partial C++ (PyCalc) is 513.901% faster |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment