Rectangle 27 4

The c++ solution for strings are quite different from the c-version. The first and most important difference is while the c using the ASCIIZ solution, the std::string and std::wstring are using two iterators (pointers) to store the actual string. The basic usage of the string classes provides a dynamic allocated solution, so in the cost of CPU overhead with the dynamic memory handling it makes the string handling more comfortable.

As you probably already know, the C doesn't contain any built-in generic string type, only provides couple of string operations through the standard library. One of the major difference between C and C++ that the C++ provides a wrapped functionality, so it can be considered as a faked generic type.

In C you need to walk through the string if you would like to know the length of it, the std::string::size() member function is only one instruction (end - begin) basically. You can safely append strings one to an other as long as you have memory, so there is no need to worry about the buffer overflow bugs (and therefore the exploits), because the appending creates a bigger buffer if it is needed.

As somebody told here before, the string is derivated from the vector functionality, in a templated way, so it makes easier to deal with the multibyte-character systems. You can define your own string type using the typedef std::basic_string specific_str_t; expression with any arbitary data type in the template parameter.

C++ string Pros: - Faster iteration in certain cases (using the size definitely, and it doesn't need the data from the memory to check if you are at the end of the string, comparing two pointers. that could make a difference with the caching) - The buffer operation are packed with the string functionality, so less worries about the buffer problems.

C++ string Cons: - due to the dynamic memory allocation stuff, the basic usage could cause impact on the performance. (fortunately you can tell to the string object what should be the original buffer size, so unless you are exceed it, it won't allocate dynamic blocks from the memory) - often weird and inconsistent names compared to other languages. this is the bad thing about any stl stuff, but you can use to it, and it makes a bit specific C++ish feeling. - the heavy usage of the templating forces the standard library to use header based solutions so it is a big impact on the compiling time.

c++ - How is std::string implemented? - Stack Overflow

c++ string std cstring
Rectangle 27 2

Imagine you pass a mutable string to a function but don't expect it to be changed. Then what if the function changes that string? In C++, for instance, you could simply do call-by-value (difference between std::string and std::string& parameter), but in C# it's all about references so if you passed mutable strings around every function could change it and trigger unexpected side effects.

c# - Why .NET String is immutable? - Stack Overflow

c# .net string immutability
Rectangle 27 2

Imagine you pass a mutable string to a function but don't expect it to be changed. Then what if the function changes that string? In C++, for instance, you could simply do call-by-value (difference between std::string and std::string& parameter), but in C# it's all about references so if you passed mutable strings around every function could change it and trigger unexpected side effects.

c# - Why .NET String is immutable? - Stack Overflow

c# .net string immutability
Rectangle 27 14

There is an important difference between std::min, std::max and fmin and fmax.

std::min(-0.0,0.0) = -0.0
std::max(-0.0,0.0) = -0.0
fmin(-0.0, 0.0) = -0.0
fmax(-0.0, 0.0) =  0.0

So std::min is not a 1-1 substitute for fmin. The functions std::min and std::max are not commutative. To get the same result with doubles with fmin and fmax one should swap the arguments

fmin(-0.0, 0.0) = std::min(-0.0,  0.0)
fmax(-0.0, 0.0) = std::max( 0.0, -0.0)
x ! = NaN
std::max(Nan,x) = NaN
std::max(x,NaN) = x
std::min(Nan,x) = NaN
std::min(x,NaN) = x
fmax(Nan,x) = x
fmax(x,NaN) = x
fmin(Nan,x) = x
fmin(x,NaN) = x

fmax can be emulated with the following code

double myfmax(double x, double y)
{
   // z > nan for z != nan is required by C the standard
   int xnan = isnan(x), ynan = isnan(y);
   if(xnan || ynan) {
        if(xnan && !ynan) return y;
        if(!xnan && ynan) return x;
        return x;
   }
   // +0 > -0 is preferred by C the standard 
   if(x==0 && y==0) {
       int xs = signbit(x), ys = signbit(y);
       if(xs && !ys) return y;
       if(!xs && ys) return x;
       return x;
   }
   return std::max(x,y);
}

This shows that std::max is a subset of fmax.

Looking at the assembly shows that Clang uses builtin code for fmax and fmin whereas GCC calls them from a math library. The assembly for clang for fmax with -O3 is

movapd  xmm2, xmm0
cmpunordsd      xmm2, xmm2
movapd  xmm3, xmm2
andpd   xmm3, xmm1
maxsd   xmm1, xmm0
andnpd  xmm2, xmm1
orpd    xmm2, xmm3
movapd  xmm0, xmm2
std::max(double, double)

However, for GCC and Clang using -Ofast fmax becomes simply

maxsd   xmm0, xmm1

So this shows once again that std::max is a subset of fmax and that when you use a looser floating point model which does not have nan or signed zero then fmax and std::max are the same. The same argument obviously applies to fmin and std::min.

Use of min and max functions in C++ - Stack Overflow

c++ c max min
Rectangle 27 5

If you are considering using multidimensional arrays, then there is one additional difference between std::array and std::vector. A multidimensional std::array will have the elements packed in memory in all dimensions, just as a c style array is. A multidimensional std::vector will not be packed in all dimensions.

Given the following declarations:

int cConc[3][5];
std::array<std::array<int, 5>, 3> aConc;
int **ptrConc;      // initialized to [3][5] via new and destructed via delete
std::vector<std::vector<int>> vConc;    // initialized to [3][5]

A pointer to the first element in the vector array (vConc) or the pointer array (ptrConc) can only be iterated through the first 5 (in this case) elements, and then there are 12 bytes (on my system) of overhead for the next vector.

This means that a std::vector> array initialized as a [3][1000] array will be much smaller in memory than one initialized as a [1000][3] array, and both will be larger in memory than a std:array allocated either way.

This also means that you can't simply pass a multidimensional vector (or pointer) array to, say, openGL without accounting for the memory overhead, but you can naively pass a multidimensional std::array to openGL and have it work out.

std::vector versus std::array in C++ - Stack Overflow

c++ arrays vector
Rectangle 27 7

The full name of string is std::string because it resides in namespace std, the namespace in which all of the C++ standard library functions, classes, and objects reside.

In your code, you've explicitly added the line using namespace std;, which lets you use anything from the standard namespace without using the std:: prefix. Thus you can refer to std::string (the real name of the string type) using the shorthand string since the compiler knows to look in namespace std for it.

There is no functionality difference between string and std::string because they're the same type. That said, there are times where you would prefer std::string over string. For example, in a header file, it is generally not considered a good idea to put the line using namespace std; (or to use any namespace, for that matter) because it can cause names in files that include that header to become ambiguous. In this setup, you would just #include <string> in the header, then use std::string to refer to the string type. Similarly, if there ever was any ambiguity between std::string and some other string type, using the name std::string would remove the ambiguity.

Whether or not you include the line using namespace std; at all is a somewhat contested topic and many programmers are strongly for or strongly against it. I suggest using whatever you're comfortable with and making sure to adopt whatever coding conventions are used when working on a large project.

std::string vs string in c++ - Stack Overflow

c++ string std
Rectangle 27 20

I see no difference between std::stream/FILE/device. Between buffering and non buffering.

  • SSD drives "tend" to slow down (lower transfer rates) as they get older (because of non working bits).

I am seeing the code run in 63 secondds. Thus a transfer rate of: 260M/s (my SSD look slightly faster than yours).

64 * 1024 * 1024 * 8 /*sizeof(unsigned long long) */ * 32 /*Chunks*/

= 16G
= 16G/63 = 260M/s
#include <stdio.h>

using namespace std;

int main()
{

    FILE* stream = fopen("binary", "w");

    for(int loop=0;loop < 32;++loop)
    {
         fwrite(a, sizeof(unsigned long long), size, stream);
    }
    fclose(stream);

}

So the C++ stream are working as fast as the underlying library will allow.

But I think it is unfair comparing the OS to an application that is built on-top of the OS. The application can make no assumptions (it does not know the drives are SSD) and thus uses the file mechanisms of the OS for transfer.

While the OS does not need to make any assumptions. It can tell the types of the drives involved and use the optimal technique for transferring the data. In this case a direct memory to memory transfer. Try writing a program that copies 80G from 1 location in memory to another and see how fast that is.

#include <fcntl.h>
#include <unistd.h>


const unsigned long long size = 64ULL*1024ULL*1024ULL;
unsigned long long a[size];
int main()
{
    int data = open("test", O_WRONLY | O_CREAT, 0777);
    for(int loop = 0; loop < 32; ++loop)
    {   
        write(data, a, size * sizeof(unsigned long long));
    }   
    close(data);
}

NOTE: My drive is an SSD drive if you have a normal drive you may see a difference between the two techniques above. But as I expected non buffering and buffering (when writting large chunks greater than buffer size) make no difference.

Have you tried the fastest method of copying files in C++

int main()
{
    std::ifstream  input("input");
    std::ofstream  output("ouptut");

    output << input.rdbuf();
}

I didn't downvote, but your buffer size is too small. I did it with the same 512 MB buffer the OP is using and I get 20 MB/s with streams vs. 90 MB/s with FILE*.

Also your way with fwrite(a, sizeof(unsigned long long), size, stream); instead of fwrite(a, 1, size*sizeof(unsigned long long), pFile); gives me 220MB/s with chunks of 64MB per write.

@Mysticial: It surprises my that buffer size makes a difference (though I believe you). The buffer is useful when you have lots of small writes so that the underlying device is not bothered with many requests. But when you are writing huge chunks there is no need for a buffer when writing/reading (on a blocking device). As such the data should be passed directly to the underlying device (thus by-passing the buffer). Though if you see a difference this would contradict this and make my wonder why the write is actually using a buffer at all.

The best solution is NOT to increase the buffer size but to remove the buffer and make write pass the data directly to the underlying device.

@Mysticial: 1) There are no small chunks => It is always large enough (in this example). In this case chunks are 512M 2) This is an SSD drive (both mine and the OP) so none of that is relevant. I have updated my answer.

performance - Writing a binary file in C++ very fast - Stack Overflow

c++ performance file-io io
Rectangle 27 20

I see no difference between std::stream/FILE/device. Between buffering and non buffering.

  • SSD drives "tend" to slow down (lower transfer rates) as they get older (because of non working bits).

I am seeing the code run in 63 secondds. Thus a transfer rate of: 260M/s (my SSD look slightly faster than yours).

64 * 1024 * 1024 * 8 /*sizeof(unsigned long long) */ * 32 /*Chunks*/

= 16G
= 16G/63 = 260M/s
#include <stdio.h>

using namespace std;

int main()
{

    FILE* stream = fopen("binary", "w");

    for(int loop=0;loop < 32;++loop)
    {
         fwrite(a, sizeof(unsigned long long), size, stream);
    }
    fclose(stream);

}

So the C++ stream are working as fast as the underlying library will allow.

But I think it is unfair comparing the OS to an application that is built on-top of the OS. The application can make no assumptions (it does not know the drives are SSD) and thus uses the file mechanisms of the OS for transfer.

While the OS does not need to make any assumptions. It can tell the types of the drives involved and use the optimal technique for transferring the data. In this case a direct memory to memory transfer. Try writing a program that copies 80G from 1 location in memory to another and see how fast that is.

#include <fcntl.h>
#include <unistd.h>


const unsigned long long size = 64ULL*1024ULL*1024ULL;
unsigned long long a[size];
int main()
{
    int data = open("test", O_WRONLY | O_CREAT, 0777);
    for(int loop = 0; loop < 32; ++loop)
    {   
        write(data, a, size * sizeof(unsigned long long));
    }   
    close(data);
}

NOTE: My drive is an SSD drive if you have a normal drive you may see a difference between the two techniques above. But as I expected non buffering and buffering (when writting large chunks greater than buffer size) make no difference.

Have you tried the fastest method of copying files in C++

int main()
{
    std::ifstream  input("input");
    std::ofstream  output("ouptut");

    output << input.rdbuf();
}

I didn't downvote, but your buffer size is too small. I did it with the same 512 MB buffer the OP is using and I get 20 MB/s with streams vs. 90 MB/s with FILE*.

Also your way with fwrite(a, sizeof(unsigned long long), size, stream); instead of fwrite(a, 1, size*sizeof(unsigned long long), pFile); gives me 220MB/s with chunks of 64MB per write.

@Mysticial: It surprises my that buffer size makes a difference (though I believe you). The buffer is useful when you have lots of small writes so that the underlying device is not bothered with many requests. But when you are writing huge chunks there is no need for a buffer when writing/reading (on a blocking device). As such the data should be passed directly to the underlying device (thus by-passing the buffer). Though if you see a difference this would contradict this and make my wonder why the write is actually using a buffer at all.

The best solution is NOT to increase the buffer size but to remove the buffer and make write pass the data directly to the underlying device.

@Mysticial: 1) There are no small chunks => It is always large enough (in this example). In this case chunks are 512M 2) This is an SSD drive (both mine and the OP) so none of that is relevant. I have updated my answer.

performance - Writing a binary file in C++ very fast - Stack Overflow

c++ performance file-io io
Rectangle 27 136

I'm going to go against the general wisdom here that std::copy will have a slight, almost imperceptible performance loss. I just did a test and found that to be untrue: I did notice a performance difference. However, the winner was std::copy.

I wrote a C++ SHA-2 implementation. In my test, I hash 5 strings using all four SHA-2 versions (224, 256, 384, 512), and I loop 300 times. I measure times using Boost.timer. That 300 loop counter is enough to completely stabilize my results. I ran the test 5 times each, alternating between the memcpy version and the std::copy version. My code takes advantage of grabbing data in as large of chunks as possible (many other implementations operate with char / char *, whereas I operate with T / T * (where T is the largest type in the user's implementation that has correct overflow behavior), so fast memory access on the largest types I can is central to the performance of my algorithm. These are my results:

std::copy   memcpy  % increase
6.11        6.29    2.86%
6.09        6.28    3.03%
6.10        6.29    3.02%
6.08        6.27    3.03%
6.08        6.27    3.03%
-Ofast -march=native -funsafe-loop-optimizations

I decided to run a test on my MD5 implementation as well. The results were much less stable, so I decided to do 10 runs. However, after my first few attempts, I got results that varied wildly from one run to the next, so I'm guessing there was some sort of OS activity going on. I decided to start over.

Same compiler settings and flags. There is only one version of MD5, and it's faster than SHA-2, so I did 3000 loops on a similar set of 5 test strings.

std::copy   memcpy      % difference
5.52        5.56        +0.72%
5.56        5.55        -0.18%
5.57        5.53        -0.72%
5.57        5.52        -0.91%
5.56        5.57        +0.18%
5.56        5.57        +0.18%
5.56        5.53        -0.54%
5.53        5.57        +0.72%
5.59        5.57        -0.36%
5.57        5.56        -0.18%

Total average decrease in speed of std::copy over memcpy: 0.11%

These results suggest that there is some optimization that std::copy used in my SHA-2 tests that std::copy could not use in my MD5 tests. In the SHA-2 tests, both arrays were created in the same function that called std::copy / memcpy. In my MD5 tests, one of the arrays was passed in to the function as a function parameter.

I did a little bit more testing to see what I could do to make std::copy faster again. The answer turned out to be simple: turn on link time optimization. These are my results with LTO turned on (option -flto in gcc):

Time (in seconds) to complete run of MD5 tests with -flto

std::copy   memcpy      % difference
5.54        5.57        +0.54%
5.50        5.53        +0.54%
5.54        5.58        +0.72%
5.50        5.57        +1.26%
5.54        5.58        +0.72%
5.54        5.57        +0.54%
5.54        5.56        +0.36%
5.54        5.58        +0.72%
5.51        5.58        +1.25%
5.54        5.57        +0.54%

Total average increase in speed of std::copy over memcpy: 0.72%

In summary, there does not appear to be a performance penalty for using std::copy. In fact, there appears to be a performance gain.

So why might std::copy give a performance boost?

First, I would not expect it to be slower for any implementation, as long as the optimization of inlining is turned on. All compilers inline aggressively; it is possibly the most important optimization because it enables so many other optimizations. std::copy can (and I suspect all real world implementations do) detect that the arguments are trivially copyable and that memory is laid out sequentially. This means that in the worst case, when memcpy is legal, std::copy should perform no worse. The trivial implementation of std::copy that defers to memcpy should meet your compiler's criteria of "always inline this when optimizing for speed or size".

However, std::copy also keeps more of its information. When you call std::copy, the function keeps the types intact. memcpy operates on void *, which discards almost all useful information. For instance, if I pass in an array of std::uint64_t, the compiler or library implementer may be able to take advantage of 64-bit alignment with std::copy, but it may be more difficult to do so with memcpy. Many implementations of algorithms like this work by first working on the unaligned portion at the start of the range, then the aligned portion, then the unaligned portion at the end. If it is all guaranteed to be aligned, then the code becomes simpler and faster, and easier for the branch predictor in your processor to get correct.

std::copy is in an interesting position. I expect it to never be slower than memcpy and sometimes faster with any modern optimizing compiler. Moreover, anything that you can memcpy, you can std::copy. memcpy does not allow any overlap in the buffers, whereas std::copy supports overlap in one direction (with std::copy_backward for the other direction of overlap). memcpy only works on pointers, std::copy works on any iterators (std::map, std::vector, std::deque, or my own custom type). In other words, you should just use std::copy when you need to copy chunks of data around.

I want to emphasize that this doesn't mean that std::copy is 2.99% or 0.72% or -0.11% faster than memcpy, these times are for the entire program to execute. However, I generally feel that benchmarks in real code are more useful than benchmarks in fake code. My entire program got that change in execution speed. The real effects of just the two copying schemes will have greater differences than shown here when taken in isolation, but this shows that they can have measurable differences in actual code.

I want to disagree with your findings, but results are results :/. However one question (I know it was a long time ago and you don't remember research, so just comment the way you think), you probably didn't look into assembly code;

In my opinion memcpy and std::copy has different implementations, so in some cases compiler optimizes surrounding code and actual memory copy code as a one integral piece of code. It other words sometimes one is better then another and even in other words, deciding which to uses is premature or even stupid optimization, because in every situation you have to do new research and, what is more, programs are usually being developed, so after some minor changes advantage of function over other may be lost.

@ST3: I would imagine that in the worst case, std::copy is a trivial inline function that just calls memcpy when it is legal. Basic inlining would eliminate any negative performance difference. I will update the post with a bit of an explanation of why std::copy might be faster.

Very informative analysis. Re Total average decrease in speed of std::copy over memcpy: 0.11%, whilst the number is correct, the results aren't statistically significant. A 95% confidence interval for the difference in means is (-0.013s, 0.025), which includes zero. As you pointed out there was variation from other sources and with your data, you'd probably say the performance is the same. For reference, the other two results are statistically significant -- the chances you'd see a difference in times this extreme by chance are about 1 in 100 million (first) and 1 in 20,000 (last).

c++ - Is it better to use std::memcpy() or std::copy() in terms to per...

c++ performance optimization
Rectangle 27 15

Since this question draws so many votes and kind of becomes an FAQ, I guess it would be better to write a separate answer to mention one significant difference between C++03 and C++11 regarding the impact of std::vector's insertion operation on the validity of iterators and references with respect to reserve() and capacity(), which the most upvoted answer failed to notice.

Reallocation invalidates all the references, pointers, and iterators referring to the elements in the sequence. It is guaranteed that no reallocation takes place during insertions that happen after a call to reserve() until the time when an insertion would make the size of the vector greater than the value of capacity().

So in C++03, it is not "unless the new container size is greater than the previous capacity (in which case all iterators and references are invalidated)" as mentioned in the other answer, instead, it should be "greater than the size specified in the most recent call to reserve()". This is one thing that C++03 differs from C++11. In C++03, once an insert() causes the size of the vector to reach the value specified in the previous reserve() call (which could well be smaller than the current capacity() since a reserve() could result a bigger capacity() than asked for), any subsequent insert() could cause reallocation and invalidate all the iterators and references. In C++11, this won't happen and you can always trust capacity() to know with certainty that the next reallocation won't take place before the size overpasses capacity().

In conclusion, if you are working with a C++03 vector and you want to make sure a reallocation won't happen when you perform insertion, it's the value of the argument you previously passed to reserve() that you should check the size against, not the return value of a call to capacity(), otherwise you may get yourself surprised at a "premature" reallocation.

However, I'd shoot any compiler who did this to me, and no jury in the land would convict me.

I didn't "fail to notice" this; it was an editorial error in C++03 that was corrected in C++11. No mainstream compiler takes advantage of the error.

c++ - Iterator invalidation rules - Stack Overflow

c++ c++11 iterator c++03 c++-faq
Rectangle 27 1

The implementation of std::begin() for vectors simply calls std::vector<T>::begin(), so there is no difference between the two in this exact case.

Where std::begin() comes into its own is in generic algorithms:

template<typename Container>
void my_algorithm(Container c) {
    using std::begin;
    using std::end;
    auto const start = begin(c);  // ADL will find the appropriate overload
    auto const finish = end(c);
    // ... rest of code ...
}

c++ - Difference between vector::begin() and std::begin() - Stack Over...

c++ vector
Rectangle 27 0

Short Answer : String is immutable whereas StringBuilder is mutable.

What does that mean ? Wiki says : In object-oriented, an immutable object is an object whose state cannot be modified after it is created. This is in contrast to a mutable object, which can be modified after it is created.

From the StringBuilder Class documentation:

The String object is immutable. Every time you use one of the methods in the System.String class, you create a new string object in memory, which requires a new allocation of space for that new object.

In situations where you need to perform repeated modifications to a string, the overhead associated with creating a new String object can be costly.

The System.Text.StringBuilder class can be used when you want to modify a string without creating a new object. For example, using the StringBuilder class can boost performance when concatenating many strings together in a loop.

What is the difference between a mutable and immutable string in C#? -...

c# string
Rectangle 27 0

Short Answer : String is immutable whereas StringBuilder is mutable.

What does that mean ? Wiki says : In object-oriented, an immutable object is an object whose state cannot be modified after it is created. This is in contrast to a mutable object, which can be modified after it is created.

From the StringBuilder Class documentation:

The String object is immutable. Every time you use one of the methods in the System.String class, you create a new string object in memory, which requires a new allocation of space for that new object.

In situations where you need to perform repeated modifications to a string, the overhead associated with creating a new String object can be costly.

The System.Text.StringBuilder class can be used when you want to modify a string without creating a new object. For example, using the StringBuilder class can boost performance when concatenating many strings together in a loop.

What is the difference between a mutable and immutable string in C#? -...

c# string