[C++-sig] object.attr(object& attrname) proposal.
hohe2 hohe
hohehohe2 at gmail.com
Sun May 25 20:38:19 CEST 2008
Hello,
I just wonder if my current idea has already been discussed (I searched the
archive a bit but didn't find one).
Curretnly object.attr() takes only string and it finally executes
PyObject_GetAttrString() or
PyObject_SetAttrString(). Those Python C/API call takes the most time and
boost::python
overhead is relatively small. It means if we can use PyObject_GetAttr() and
PyObject_SetAttr()
with boost::python then getting/setting attribute can become much faster,
because
PyObject_*Attr() is much faster than PyObject_*AttrString().
So my proposal is:
If char const* is passed to objecjt.attr(), it uses PyObject_GetAttrStrng()
or PyObject_SetAttrStrng().
If object is passed to objecjt.attr(), it takes the object as a Python
string object and uses PyObject_GetAttr() or PyObject_SetAttr().
If attr() behaves like this, it can be useful when there are lots of objects
which you know have
the same attribute name. You can save time by first making a
boost::python::object and passing
it to every object's attr() inside a loop.
I just made a bit of modification to boost:python locally and did a quick
test, like
test 1:
for(int i = 0; i < n; ++i)
{
omain.attr(attrname) = 444; //attrname is a char const*
}
test 2:
for(int i = 0; i < n; ++i)
{
object o = omain.attr(attrname); //attrname is a char const*
}
test 3:
for(int i = 0; i < n; ++i)
{
omain.attr(oaaaa) = 444; //oaaaa is boost::python::object that
represents a string
}
test 4:
for(int i = 0; i < n; ++i)
{
object o = omain.attr(oaaaa); //oaaaa is boost::python::object that
represents a string
}
and it reasonably reflected the difference between PyObject_*Attr() and
PyObject_*AttrString.
test 1 :2783ms
test 2 :2357ms
test 3 :1882ms
test 4 :1267ms
I'd like to know your opinions about this modification.
- Koichi
p.s.
I made the modification for a test and it may be wrong (or even evil), but
I'll write it here anyway.
-----------------------------------------------------------------------------
diff -urN python/object_attributes.hpp python_p/object_attributes.hpp
--- python/object_attributes.hpp 2008-03-22 17:45:00.000000000 +0900
+++ python_p/object_attributes.hpp 2008-05-25 21:58:10.000000000 +0900
@@ -17,6 +17,7 @@
{
typedef char const* key_type;
static object get(object const& target, char const* key);
+ static object get(object const& target, object const& key);
};
struct attribute_policies : const_attribute_policies
@@ -25,6 +26,18 @@
static void del(object const&target, char const* key);
};
+struct const_objattribute_policies
+{
+ typedef object const key_type;
+ static object get(object const& target, object const& key);
+};
+
+struct objattribute_policies : const_objattribute_policies
+{
+ static object const& set(object const& target, object const& key,
object const& value);
+ static void del(object const&target, object const& key);
+};
+
//
// implementation
//
@@ -42,11 +55,30 @@
return const_object_attribute(x, name);
}
+template <class U>
+inline object_objattribute object_operators<U>::attr(object const& name)
+{
+ object_cref2 x = *static_cast<U*>(this);
+ return object_objattribute(x, name);
+}
+
+template <class U>
+inline const_object_objattribute object_operators<U>::attr(object const&
name) const
+{
+ object_cref2 x = *static_cast<U const*>(this);
+ return const_object_objattribute(x, name);
+}
+
inline object const_attribute_policies::get(object const& target, char
const* key)
{
return python::getattr(target, key);
}
+inline object const_objattribute_policies::get(object const& target, object
const& key)
+{
+ return python::getattr(target, key);
+}
+
inline object const& attribute_policies::set(
object const& target
, char const* key
@@ -56,6 +88,15 @@
return value;
}
+inline object const& objattribute_policies::set(
+ object const& target
+ , object const& key
+ , object const& value)
+{
+ python::setattr(target, key, value);
+ return value;
+}
+
inline void attribute_policies::del(
object const& target
, char const* key)
@@ -63,6 +104,13 @@
python::delattr(target, key);
}
+inline void objattribute_policies::del(
+ object const& target
+ , object const& key)
+{
+ python::delattr(target, key);
+}
+
}}} // namespace boost::python::api
#endif // OBJECT_ATTRIBUTES_DWA2002615_HPP
diff -urN python/object_core.hpp python_p/object_core.hpp
--- python/object_core.hpp 2008-03-22 17:45:00.000000000 +0900
+++ python_p/object_core.hpp 2008-05-25 21:58:36.000000000 +0900
@@ -59,6 +59,8 @@
struct const_attribute_policies;
struct attribute_policies;
+ struct const_objattribute_policies;
+ struct objattribute_policies;
struct const_item_policies;
struct item_policies;
struct const_slice_policies;
@@ -67,6 +69,8 @@
typedef proxy<const_attribute_policies> const_object_attribute;
typedef proxy<attribute_policies> object_attribute;
+ typedef proxy<const_objattribute_policies> const_object_objattribute;
+ typedef proxy<objattribute_policies> object_objattribute;
typedef proxy<const_item_policies> const_object_item;
typedef proxy<item_policies> object_item;
typedef proxy<const_slice_policies> const_object_slice;
@@ -108,6 +112,8 @@
//
const_object_attribute attr(char const*) const;
object_attribute attr(char const*);
+ const_object_objattribute attr(object const&) const;
+ object_objattribute attr(object const&);
// item access
//
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20080526/86a53f8e/attachment.htm>
More information about the Cplusplus-sig
mailing list