New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Slow performance on python wrapper #275
Comments
For some reason, attrib array access(e.g. Parsing
Please try tinyobjloader/python/sample.py Line 76 in 4cb4af6
NOTE: numpy API is only available in |
Yea, agreed, the This is the loader code I'm using. It's not super elegant yet, and I imagine we could improve this interface some, but it is very fast. |
Hey guys, thanks for your fast response... yeah, I'll give it a shot to numpy as that seems a much faster solution. @paulmelnikow But... is that code of yours dealing also with normals and texcoords or just with positions? (numpy newbie here) I'm still trying to figure out how to create my vertices & faces... The numpy interface seems to be a bit trickier than the good old python lists :) |
The positions are in Yea, the performance gains from NumPy can be really huge, though it definitely has a bit of a learning curve. |
Ok guys, I think this issue has already become clear and we can close it, can't we? Only thing I'd would probably add, while numpy performance seems to be great in comparison to vanilla python it's adding an extra dependency that may or may not be convenient for some people. For example, let's say you want to deploy your python app using tinyobjloader using nuitka, by adding numpy you'll be probably adding a lot of overhead to the compilation (few months ago when checked compiling numpy was like ~20min) Anyway, not sure how difficult would be getting rid of such dependency and providing a direct access to something like...
Said otherwise, direct access to the filled parsed data without any intermediate layer.. Of course, that's up to you to think about. To me, this has become quite clear. Although figuring out how to use the numpy accessors isn't very easy for users. Thank you very much. |
Out of curiosity, have you tried assigning I'm wondering if the for loop is what's making your code slow or if it's that you need to use byte arrays rather than native python data structures. What you're proposing is an expanded layer of convenience accessors in C++, along with Python bindings, which is possible. Another approach, which is probably less to maintain, could be to provide the byte arrays to Python (even if you're not using NumPy). |
I am revisiting this issue and found assigning variable in the outer loop solved the issue(execution time become less than 0.01 secs) vertices = attrib.vertices # <- Make things fast!
for shape in reader.GetShapes():
num_vertices += len(attrib.vertices)
num_normals += len(attrib.normals)
num_texcoords += len(attrib.texcoords)
for f in shape.mesh.indices:
v = vertices[f.vertex_index * 3 + 0] It looks pybind always create a python object(?) of Another way is providing direct array indexing access API which also gives enough performance(less than 0.01 secs) py::class_<attrib_t>(tobj_module, "attrib_t")
.def(py::init<>())
.def_readonly("vertices", &attrib_t::vertices)
.def("vertices_at", [](attrib_t &instance, ssize_t idx) {
// TODO: Return triple(x, y, z)
return instance.vertices[idx];
}) ...
v = attrib.vertices_at(0)
... I'd like to go with this API(along with |
@paulmelnikow FYI I have tried bytearray and Python buffer protocol(https://pybind11.readthedocs.io/en/stable/advanced/pycpp/numpy.html#buffer-protocol) but found both are not suited for tinyobj usecase(it simply exposes memory object to Python world so the user must know the buffer layout of each data to access the element in Python world) |
Let's start by considering this snippet:
And here's the link to both mcve.obj and mcve.mtl, this object is a very small & trivial scene, that looks like this:
Problem being... if you run that snippet you'll get this output:
That's really slow & unusable for such a trivial scene. I wanted to san miguel's scene from https://casual-effects.com/data/ but after seeing these poor results on such a trivial scene I'm not even considering it till I figure out how to proceed here.
So yeah, the main question would be, how could we use the tinyobjloader effectively on python so we can test real-world scenes?
Thanks in advance.
Ps. I've got allocated a huge chunk of memory for interleaved data (vertices+normals+texcoords) so I'm not sure how difficult would be providing a wrapper to make a fast memcpy or similar... Main problem seems to be the whole overhead of wrapping c++ to python
The text was updated successfully, but these errors were encountered: