Hello Kent,
First:
I have not really tried this but I just prototyped it and it could be useful if
you want to try to track down the cases a little more programmatically, and
care to mess with tr1 typetraits a little. Consider adding the following to
itkMacro.h:
#include <tr1/type_traits>
#include <tr1/type_compare>
template < typename TOuttype, typename TIntype >
TOuttype itk_dynamic_cast( TIntype in )
{
static_assert( std::tr1::is_pointer<TOuttype>::value );
static_assert( std::tr1::is_base_of<TIntype, TOuttype>::value );
return dynamic_cast<TOuttype>( in );
}
#define dynamic_cast itk_dynamic_cast
Second:
While I am aware the use of dynamic_cast is not high performance it didn't
bother me being used in for this case. So I modified the performance test Matt
linked with the following additional cases:
res = 0;
start = getticks();
for (size_t i=0 ; i<N ; ++i) {
const char baseName[] = "IndexedDataObject";
std::ostringstream oss;
oss << baseName << N;
std::string s = oss.str();
res += s.size();
}
end = getticks();
timed = elapsed(end, start);
timings[17].push_back(timed);
res = 0;
start = getticks();
for (size_t i=0 ; i<N ; ++i) {
char buf[100];
sprintf(buf, "IndexedDataObject%u", static_cast<unsigned int>(N));
std::string s(buf);
res += s.size();
}
end = getticks();
timed = elapsed(end, start);
timings[18].push_back(timed);
These is based on code that is in the GetInput methods. This following is the
results on my i7 laptop:
reinterpret_cast known-type: with relative 1.00, fastest 11686168.00, average
12120401.33, stddev 298867.57
virtual function + reinterpret_cast: with relative 1.78, fastest 21040604.00,
average 21536555.33, stddev 464657.48
member variable + reinterpret_cast: with relative 1.10, fastest 13127058.00,
average 13311370.00, stddev 227979.57
dynamic_cast same-type-base success: with relative 0.97, fastest 11514018.00,
average 11717135.50, stddev 125301.84
dynamic_cast same-type-level1 success: with relative 2.94, fastest
34896278.00, average 35578390.00, stddev 393787.56
dynamic_cast same-type-level2 success: with relative 2.88, fastest
34403850.00, average 34912766.67, stddev 516410.80
dynamic_cast same-type-level3 success: with relative 2.84, fastest
33781284.00, average 34444748.67, stddev 593710.46
dynamic_cast level1-to-base success: with relative 1.05, fastest 12517034.00,
average 12768522.83, stddev 322468.58
dynamic_cast level2-to-base success: with relative 1.01, fastest 12024095.00,
average 12287761.83, stddev 245272.40
dynamic_cast level3-to-base success: with relative 1.03, fastest 12074146.00,
average 12427744.83, stddev 386862.93
dynamic_cast level2-to-level1 success: with relative 3.28, fastest
39064702.00, average 39723110.50, stddev 601394.77
dynamic_cast level3-to-level1 success: with relative 3.93, fastest
46206012.00, average 47576171.83, stddev 1193834.23
dynamic_cast level3-to-level2 success: with relative 3.38, fastest
40250794.00, average 40943911.83, stddev 454434.63
dynamic_cast onebase-to-twobase fail: with relative 2.00, fastest 23874560.00,
average 24276072.83, stddev 1132888.98
dynamic_cast onelevel1-to-twobase fail: with relative 2.57, fastest
30602545.00, average 31203997.50, stddev 527747.22
dynamic_cast onelevel2-to-twobase fail: with relative 3.08, fastest
37019228.00, average 37358361.00, stddev 269371.47
dynamic_cast onelevel3-to-twobase fail: with relative 3.74, fastest
44848942.00, average 45287361.83, stddev 584046.88
ostringstream: with relative 144.16, fastest 1705792767.00, average
1747226021.83, stddev 20540335.54
sprintf: with relative 47.74, fastest 575666370.00, average 578647874.17,
stddev 3708284.83
Brad
On Jul 23, 2012, at 5:36 PM, Matt McCormick wrote:
> On Mon, Jul 23, 2012 at 9:22 PM, Williams, Norman K
> <[email protected]> wrote:
>> RE unnecessary casts: Personally, I think casts uglify code and should
>> only be there as a way for the programmer to communicate intention to the
>> compiler.
>>
>>
>> RE adding dynamic casts: I don't know what the real overhead of a
>> dynamic_cast vs a static_cast entails, and I suspect it varies depending
>> on what compiler you use. Determining if it is logically impossible for
>> dynamic_cast to fail isn't easy; and not all filters are written in such a
>> way that prevent assigning bad inputs, like adding an Image where a Mesh
>> is expected.
>>
>> I like Sean McBride's idea of a debug-only assert. In fact it might be
>> useful to use static_cast for release and dynamic_cast + assert(rval != 0)
>> for debug builds.
>
> Keep in mind that static_cast is done at compile time and dynamic_cast
> is done during runtime. My understanding is that dynamic_cast can be
> "expensive", and an assert is not saving anything relative to the cost
> of the dynamic_cast.
>
> Some performance numbers:
>
> http://tinodidriksen.com/2010/04/14/cpp-dynamic-cast-performance/
>
> Thanks,
> Matt
>
>>
>> On 7/23/12 3:58 PM, "Matt McCormick" <[email protected]> wrote:
>>
>>>>
>>>> So the question is this: do we keep static_cast where they aren't
>>>> needed?
>>>
>>> Since it is a matter of human-readability, something consistent is
>>> preferred, whatever that may be...
>>>
>>>> and should we add dynamic_cast in the frequent case where an input or
>>>> output of a filter is assumed to be of a particular type?
>>>>
>>>
>>> If it is not logically possible in the code for the dynamic_cast to
>>> fail, and given the GetInput/GetOutput consequences, avoiding
>>> unnecessary overhead seems best.
>>
>>
>>
>> ________________________________
>> Notice: This UI Health Care e-mail (including attachments) is covered by the
>> Electronic Communications Privacy Act, 18 U.S.C. 2510-2521, is confidential
>> and may be legally privileged. If you are not the intended recipient, you
>> are hereby notified that any retention, dissemination, distribution, or
>> copying of this communication is strictly prohibited. Please reply to the
>> sender that you have received the message in error, then delete it. Thank
>> you.
>> ________________________________
>> _______________________________________________
>> Powered by www.kitware.com
>>
>> Visit other Kitware open-source projects at
>> http://www.kitware.com/opensource/opensource.html
>>
>> Kitware offers ITK Training Courses, for more information visit:
>> http://kitware.com/products/protraining.php
>>
>> Please keep messages on-topic and check the ITK FAQ at:
>> http://www.itk.org/Wiki/ITK_FAQ
>>
>> Follow this link to subscribe/unsubscribe:
>> http://www.itk.org/mailman/listinfo/insight-developers
> _______________________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
>
> Kitware offers ITK Training Courses, for more information visit:
> http://kitware.com/products/protraining.php
>
> Please keep messages on-topic and check the ITK FAQ at:
> http://www.itk.org/Wiki/ITK_FAQ
>
> Follow this link to subscribe/unsubscribe:
> http://www.itk.org/mailman/listinfo/insight-developers
_______________________________________________
Powered by www.kitware.com
Visit other Kitware open-source projects at
http://www.kitware.com/opensource/opensource.html
Kitware offers ITK Training Courses, for more information visit:
http://kitware.com/products/protraining.php
Please keep messages on-topic and check the ITK FAQ at:
http://www.itk.org/Wiki/ITK_FAQ
Follow this link to subscribe/unsubscribe:
http://www.itk.org/mailman/listinfo/insight-developers