<p dir="ltr">Hi David,</p>
<p dir="ltr">Thanks for your feedback, tomorrow I will do the tests that you suggested, and will report back.<br>
Best regards,</p>
<p dir="ltr">Marco Sambin</p>
<p dir="ltr">> Il 12/giu/2014 20:06 "David Gobbi" <<a href="mailto:david.gobbi@gmail.com">david.gobbi@gmail.com</a>> ha scritto:<br>
><br>
>> I made a major typo in my last email.  I meant to say "try<br>
>> repeating the tests with SetDataByteOrderToLittleEndian()"<br>
>><br>
>> On Thu, Jun 12, 2014 at 11:55 AM, David Gobbi <<a href="mailto:david.gobbi@gmail.com">david.gobbi@gmail.com</a>> wrote:<br>
>> > Hi Marco,<br>
>> ><br>
>> > Try repeating the tests with SetDataByteOrderToBigEndian().  If the<br>
>> > byte reordering is really the most CPU-intensive part of the read, as<br>
>> > I suspect, then this should reduce both times but perhaps one more<br>
>> > than the other.<br>
>> ><br>
>> > Other than that, I don't have any guesses.  In vtkImageReader.cxx, I<br>
>> > notice that it reads into a buffer where it performs the byte swap,<br>
>> > whereas vtkImageReader2.cxx doesn't use a buffer.  If this makes any<br>
>> > difference at all, though, it should be in favor of vtkImageReader2<br>
>> > (unless CPU cache misses are involved).<br>
>> ><br>
>> > The only way to be sure is to run the tests in a C++ profiler, on OS X<br>
>> > I use "Instruments" but I've never done profiling on Windows.  On a<br>
>> > related note, one thing that I did find via profiling is that fread()<br>
>> > was 4x faster than doing read() on a C++ fstream.  But this was only<br>
>> > meaningful when reading from disk cache.  When the reads were hitting<br>
>> > the actual disk, the difference was negligible.<br>
>> ><br>
>> >   David<br>
>> ><br>
>> ><br>
>> ><br>
>> > On Thu, Jun 12, 2014 at 11:37 AM, Marco Sambin <<a href="mailto:m.sambin@gmail.com">m.sambin@gmail.com</a>> wrote:<br>
>> >> Hi David,<br>
>> >><br>
>> >> first of all, thank you for your reply.<br>
>> >> No, the difference is not related to disk caching issues. Here are two test<br>
>> >> methods that I've written:<br>
>> >><br>
>> >><br>
>> >> public static void testVTKImageReader()<br>
>> >>   {<br>
>> >>     long startTime = System.currentTimeMillis();<br>
>> >><br>
>> >>     vtkImageReader testReaderVTK =  new vtkImageReader();<br>
>> >>     testReaderVTK.FileLowerLeftOn();<br>
>> >>     testReaderVTK.SetFileDimensionality(3);<br>
>> >>     testReaderVTK.SetFileName("C:\\Test\\SeriesVolume.raw");<br>
>> >><br>
>> >>     testReaderVTK.SetDataExtent(0, 511,<br>
>> >>                           0, 511,<br>
>> >>                           0, 520);<br>
>> >>     testReaderVTK.SetDataSpacing(1.0, 1.0, 1.0);<br>
>> >>     testReaderVTK.SetDataOrigin(0.0, 0.0, 0.0);<br>
>> >>     testReaderVTK.SetDataScalarTypeToUnsignedShort();<br>
>> >>     testReaderVTK.SetDataByteOrderToBigEndian();<br>
>> >>     testReaderVTK.UpdateWholeExtent();<br>
>> >><br>
>> >>     long endTime = System.currentTimeMillis();<br>
>> >><br>
>> >>     System.out.println("Volume read by vtkImageReader. Total time millis = "<br>
>> >> + (endTime - startTime));<br>
>> >>   }<br>
>> >><br>
>> >>   public static void testVTKImageReader2()<br>
>> >>   {<br>
>> >>     long startTime = System.currentTimeMillis();<br>
>> >><br>
>> >>     vtkImageReader2 testReaderVTK =  new vtkImageReader2();<br>
>> >>     testReaderVTK.FileLowerLeftOn();<br>
>> >>     testReaderVTK.SetFileDimensionality(3);<br>
>> >>     testReaderVTK.SetFileName("C:\\Test\\SeriesVolume.raw");<br>
>> >><br>
>> >>     testReaderVTK.SetDataExtent(0, 511,<br>
>> >>                           0, 511,<br>
>> >>                           0, 520);<br>
>> >>     testReaderVTK.SetDataSpacing(1.0, 1.0, 1.0);<br>
>> >>     testReaderVTK.SetDataOrigin(0.0, 0.0, 0.0);<br>
>> >>     testReaderVTK.SetDataScalarTypeToUnsignedShort();<br>
>> >>     testReaderVTK.SetDataByteOrderToBigEndian();<br>
>> >>     testReaderVTK.UpdateWholeExtent();<br>
>> >><br>
>> >>     long endTime = System.currentTimeMillis();<br>
>> >><br>
>> >>     System.out.println("Volume read by vtkImageReader2. Total time millis =<br>
>> >> " + (endTime - startTime));<br>
>> >>   }<br>
>> >><br>
>> >> After doing a couple of "cold starts" in order to "warm up" disk caches, on<br>
>> >> my test PC method "testVTKImageReader()" executes in around 2 seconds, while<br>
>> >> method "testVTKImageReader2()" executes in around 10 seconds.<br>
>> >> I've tried executing testVTKImageReader() before and testVTKImageReader2()<br>
>> >> after or viceversa during the same execution session, but the result doesn't<br>
>> >> change: testVTKImageReader() is always around 5 times faster than<br>
>> >> testVTKImageReader2().<br>
>> >><br>
>> >> Can you guess why?<br>
>> >> Thanks and best regards,<br>
>> >><br>
>> >> Marco Sambin<br>
>> >><br>
>> >><br>
>> >><br>
>> >> On Thu, Jun 12, 2014 at 7:12 PM, David Gobbi <<a href="mailto:david.gobbi@gmail.com">david.gobbi@gmail.com</a>> wrote:<br>
>> >>><br>
>> >>> Hi Marco,<br>
>> >>><br>
>> >>> When used the way they are in your example code, vtkImageReader and<br>
>> >>> vtkImageReader2 should be exactly the same speed.<br>
>> >>><br>
>> >>> Can you explain your testing methodology in more detail?  I suspect that<br>
>> >>> when you tested vtkImageReader2, it was reading from disk, and when<br>
>> >>> testing vtkImageReader, it was reading from disk cache.  The only part<br>
>> >>> of the "read" operation that actually requires any CPU time is the byte<br>
>> >>> swapping, but that should be identical for the two readers.<br>
>> >>><br>
>> >>>  - David<br>
>> >>><br>
>> >>><br>
>> >>> On Thu, Jun 12, 2014 at 11:00 AM, Marco Sambin <<a href="mailto:m.sambin@gmail.com">m.sambin@gmail.com</a>> wrote:<br>
>> >>> > Hi all.<br>
>> >>> > I am reading a volume made up of a set of "slices" stored in a single<br>
>> >>> > large<br>
>> >>> > raw file, containing just the raw pixels of each slice (unsigned short<br>
>> >>> > values), one slice after the other. I know in advance image size,<br>
>> >>> > position,<br>
>> >>> > orientation and spacing information related to each slice.<br>
>> >>> > I used to read my input raw volume through the vtkImageReader2 class, as<br>
>> >>> > documentation of vtkImageReader states:<br>
>> >>> ><br>
>> >>> > "vtkImageReader provides methods needed to read a region from a file. It<br>
>> >>> > supports both transforms and masks on the input data, but as a result is<br>
>> >>> > more complicated and slower than its parent class vtkImageReader2."<br>
>> >>> ><br>
>> >>> > so I always assumed vtkImageReader2 to be faster than vtkImageReader to<br>
>> >>> > read<br>
>> >>> > a simple volume made up of a set of raw slices.<br>
>> >>> > This until today, when I tried replacing my instance of vtkImageReader2<br>
>> >>> > with<br>
>> >>> > an instance of vtkImageReader. Guess what? My volume reading code now<br>
>> >>> > executes around 10 times faster!<br>
>> >>> ><br>
>> >>> > Is this expected? Can you guess what may be the reason for such a<br>
>> >>> > significant difference in performance between vtkImageReader2 and<br>
>> >>> > vtkImageReader, the latter being much faster in my scenario (despite<br>
>> >>> > what<br>
>> >>> > the documentation states)?<br>
>> >>> ><br>
>> >>> > For completeness, I am using VTK 6.1 64-bit from Java 7 64-bit, under<br>
>> >>> > Windows 7 Professional 64-bit. Here is a code fragment showing how I<br>
>> >>> > configure my reader:<br>
>> >>> ><br>
>> >>> > [...]<br>
>> >>> > imageReaderVTK =  new vtkImageReader(); // much slower if I use<br>
>> >>> > "vtkImageReader2" here<br>
>> >>> > imageReaderVTK.FileLowerLeftOn();<br>
>> >>> > imageReaderVTK.SetFileDimensionality(3);<br>
>> >>> > imageReaderVTK.SetFileName(curRawVolFile.getAbsolutePath());<br>
>> >>> > imageReaderVTK.SetDataExtent(0, sliceCols - 1,<br>
>> >>> >                       0, sliceRows - 1,<br>
>> >>> >                       0, numOfUsedImages - 1);<br>
>> >>> > imageReaderVTK.SetDataSpacing(xSpacing, ySpacing, zSpacing);<br>
>> >>> > imageReaderVTK.SetDataOrigin(0.0, 0.0, 0.0);<br>
>> >>> > imageReaderVTK.SetDataScalarTypeToUnsignedShort();<br>
>> >>> > imageReaderVTK.SetDataByteOrderToBigEndian();<br>
>> >>> > imageReaderVTK.UpdateWholeExtent();<br>
>> >>> > [...]<br>
>> >>> ><br>
>> >>> > My typical input raw volume is made up of around 500 slices, each one<br>
>> >>> > 512x512 pixels large.<br>
>> >>> ><br>
>> >>> > Thanks in advance for your feedback.<br>
>> >>> > Best regards,<br>
>> >>> ><br>
>> >>> > Marco Sambin<br>
>> >><br>
>> >><br>
</p>