On 02/17/2010 12:51 AM, Kenton Varda wrote:
On Tue, Feb 16, 2010 at 2:47 PM, Romain Francois
<romain.francois.r.enthusi...@gmail.com
<mailto:romain.francois.r.enthusi...@gmail.com>> wrote:
Thanks for the feedback.
On 02/16/2010 10:44 PM, Kenton Varda wrote:
GeneratedMessageReflection is an internal class used by the protobuf
implementation. Currently, users are not allowed to use it
directly,
because we may change it at any time. You're suggesting that we
promote
it to a public interface, which has implications with regard to
maintenance costs and implementation agility.
I understand that.
I'm not necessarily suggesting to make this particular class public,
but am looking for some way to iterate over the elements of a
repeated field.
The Reflection interface already provides a way -- FieldSize() and
GetRepeatedX(). The only problem is that it's a bit slower than the
generated accessors because these methods aren't inlineable.
Sure. I meant "STL algorithms" iterating.
BTW, have you observed an actual performance problem or are you just
speculating that this performance difference may be a problem for you?
In similar (non protobuf-related) settings, we have observed quite a bit
of difference between using plain loops and accessors as opposed to
iterators.
But this is mainly speculation on the performance.
Also, this looks nicer :
double sum = std::accumulate( y.begin(), y.end(), 0.0 ) ;
than this:
double x = 0.0 ;
for( int i=0; i<n; i++){
x += ref.GetRepeatedDouble( message, field, i ) ;
}
... but I suppose we can wrap these in our own iterators, but then I
guess we'd have to resort to some sort of proxy to deal with
GetRepeatedDouble and SetRepeatedDouble.
On the same score, if I want to increase the number of elements in a
repeated field, I have to do it one by one right ? I can't do
something like first reserve space, and then fill the generated
space. Does that mean that memory is reallocated each time ?
No, adding an element is O(1), even if you haven't reserved space. It
works the same way std::vector works.
But when you use std::vector, it is best to first reserve the target
size as opposed to create an empty vector and push_back each element.
What you would really need to
use is dynamic_cast. My golden rule of dynamic_cast is that it
should
only be used for optimization, and you must provide an
implementation
for the case where dynamic_cast always returns NULL.
But dynamic_cast is a runtime thing, where TMP dispatch happens at
compile time.
GetReflection() returns Reflection*, NOT GeneratedMessageReflection*.
Therefore the compile has no idea which type was returned, therefore
you *must* use a runtime check. That's my point -- your template
dispatch doesn't accomplish anything in this context.
Ah ok. Sorry about that.
In your case, you
are doing this, so that should be fine.
On Sat, Feb 13, 2010 at 1:16 AM, Romain Francois
<romain.francois.r.enthusi...@gmail.com
<mailto:romain.francois.r.enthusi...@gmail.com>
<mailto:romain.francois.r.enthusi...@gmail.com
<mailto:romain.francois.r.enthusi...@gmail.com>>> wrote:
Hello,
Thanks for the answers.
Maybe I should give some more background on why this is of
interest
to me. In RProtoBuf, we essentially only use the reflection
api so
that we can dynamically load new proto message types at
runtime, etc
... we don't use protoc and therefore have no access to the
generated classes.
In the class "GeneratedMessageReflection", there are
templates such as :
template <typename Type>
inline Type GetRepeatedField(const Message& message,
const FieldDescriptor* field,
int index) const;
but they are private ? Why ?
>From what I can read of the code, methods like GetRepeatedInt32
get expanded out of :
PASSTYPE GeneratedMessageReflection::GetRepeated##TYPENAME(
\
const Message& message, \
const FieldDescriptor* field, int index) const { \
USAGE_CHECK_ALL(GetRepeated##TYPENAME, REPEATED,
CPPTYPE); \
if (field->is_extension()) { \
return GetExtensionSet(message).GetRepeated##TYPENAME(
\
field->number(), index); \
} else { \
return GetRepeatedField<TYPE>(message, field, index);
\
} \
} \
so doing things like this code
for( int i=0; i<size; i++){
INTEGER(res)[i] = (int) ref->GetRepeatedInt32(
*message,
fieldDesc,
i ) ;
}
is going to be not as efficient as if I could directly
iterate over
the repeated field using RepeatedField::iterator
Instead of extending the Reflection interface, what about
making the
templates public in GeneratedMessageReflection and then
maybe use
some sort of trait to indicate whether that the instance of
Reflection I have access to has these templates.
Something like :
template <typename _T, _T _V> struct integral_constant {
static const _T value = _V;
typedef _T value_type;
typedef integral_constant<_T,_V> type;
};
typedef integral_constant<bool, true> true_type;
typedef integral_constant<bool, false> false_type;
struct reflection_has_templates{} ;
struct reflection_no_templates{} ;
template <typename T> struct has_templates : public
false_type{};
template<> struct has_templates<GeneratedMessageReflection>
: public
true_type{} ;
So that using this trait, I can dispatch between :
- suboptimal implementation when the templates are not there
- optimal implementation using RepeatedField::iterator when
they are
available.
It adds nothing to the Reflection interface.
Romain
On 02/12/2010 10:37 PM, Kenton Varda wrote:
Yeah, it would add a lot of complication and reduce the
flexibility of
the Reflection interface. We don't want to require repeated
fields to
be implemented in terms of RepeatedField or
RepeatedPtrField.
On Fri, Feb 12, 2010 at 12:11 PM, Jason Hsueh
<jas...@google.com <mailto:jas...@google.com>
<mailto:jas...@google.com <mailto:jas...@google.com>>
<mailto:jas...@google.com <mailto:jas...@google.com>
<mailto:jas...@google.com <mailto:jas...@google.com>>>> wrote:
+kenton
Kenton may have a better answer, but I surmise that
it's to
avoid
tying the Reflection interface to implementation
details. A
Message
implementation might not use RepeatedField at all.
The original
version of protobufs used a different class to represent
repeated
fields, so it wouldn't have been possible to implement
Reflection
for the original version if the interface required
access to
RepeatedField. So maybe the reason is historical.
Recent changes
have been made that would make this technically
possible.
However,
adding methods to get direct access to the RepeatedField
would still
expand the Reflection interface quite a bit. I'll
defer to
Kenton on
that.
On Fri, Feb 12, 2010 at 2:51 AM, Romain Francois
<romain.francois.r.enthusi...@gmail.com
<mailto:romain.francois.r.enthusi...@gmail.com>
<mailto:romain.francois.r.enthusi...@gmail.com
<mailto:romain.francois.r.enthusi...@gmail.com>>
<mailto:romain.francois.r.enthusi...@gmail.com
<mailto:romain.francois.r.enthusi...@gmail.com>
<mailto:romain.francois.r.enthusi...@gmail.com
<mailto:romain.francois.r.enthusi...@gmail.com>>>> wrote:
Why not ? It seems reasonnable to want to use e.g.
std::copy and
friends.
On the documentation it says :
"
Most users will not ever use a RepeatedField
directly;
they will
use the get-by-index, set-by-index, and add
accessors
that are
generated for all repeated fields
"
What if I do want to use RepeatedField ?
Romain
On 02/11/2010 06:50 PM, Jason Hsueh wrote:
No, there isn't a way to get the
RepeatedField from the
reflection
interface. You can only do so via the generated
interface.
On Thu, Feb 11, 2010 at 5:57 AM, Romain Francois
<romain.francois.r.enthusi...@gmail.com
<mailto:romain.francois.r.enthusi...@gmail.com>
<mailto:romain.francois.r.enthusi...@gmail.com
<mailto:romain.francois.r.enthusi...@gmail.com>>
<mailto:romain.francois.r.enthusi...@gmail.com
<mailto:romain.francois.r.enthusi...@gmail.com>
<mailto:romain.francois.r.enthusi...@gmail.com
<mailto:romain.francois.r.enthusi...@gmail.com>>>
<mailto:romain.francois.r.enthusi...@gmail.com
<mailto:romain.francois.r.enthusi...@gmail.com>
<mailto:romain.francois.r.enthusi...@gmail.com
<mailto:romain.francois.r.enthusi...@gmail.com>>
<mailto:romain.francois.r.enthusi...@gmail.com
<mailto:romain.francois.r.enthusi...@gmail.com>
<mailto:romain.francois.r.enthusi...@gmail.com
<mailto:romain.francois.r.enthusi...@gmail.com>>>>> wrote:
Hello,
How can I get hold of a RepeatedField
object to
manage a
repeated
field in C++.
In RProtoBuf, we do a lot of :
for( int i=0; i<size; i++){
INTEGER(res)[i] = (int)
ref->GetRepeatedInt32(
*message,
fieldDesc,
i ) ;
}
where essentially the INTEGER macro gives a
pointer to
the beginning
of the int array we are filling.
I'd like to replace this using e.g std::copy
RepeatedField field ;
std::copy( field.begin(), field.end(),
INTEGER(res) ) ;
but I can't find how to actually get
hold of a
RepeatedField object.
Is it possible ?
Romain
--
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
http://romainfrancois.blog.free.fr
|- http://tr.im/OcQe : Rcpp 0.7.7
|- http://tr.im/O1wO : highlight 0.1-5
`- http://tr.im/O1qJ : Rcpp 0.7.6
--
You received this message because you are subscribed to the Google Groups "Protocol
Buffers" group.
To post to this group, send email to proto...@googlegroups.com.
To unsubscribe from this group, send email to
protobuf+unsubscr...@googlegroups.com.
For more options, visit this group at
http://groups.google.com/group/protobuf?hl=en.