Critique of Valarray :: Apply ().
I really need to do overall =, - =, max, etc., and find that Valarray is a very good thing, use this thing to help the operation.
Then I found a better Valarray :: Apply (): Its description is transmitted to Apply (), apply () can return a Valarray that is too much to be active.
That is to say, if I want to multiply each value of an array A by 2 to get a new array, you can write: int F (INT i) {returni i * 2;}
Valarray
Blahblah ... / * assigns A to {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} * /
B = a.apply (f); / * then B is turned into {2, 4, 6, 8, 10, 12, 14, 16, 18, 20} * /
But I am very acceptable to the whole process, write a constructor, copy constructor, and Operator = has the output class to detect, and find that the app is called many constructors and Operator = (). So open the source code of
Valarray <_ty> Apply (_ty, size ()); _f (_ptr [_i]));} #define _valop (Type, Length, RHS) / Valarray
In this way, I think Apply () is a very low efficiency. Because to make each element of a A, it will be received by 2, it will: 1. Generate a temporary Valarray: _ANS, length 10.2. Call f () assign a value, cycle 10 times. 3. When Return is generated, a temporary object used to save the return value is also 10, and run the COPY Constructor to copy _ans to it 4. Then call Operator = () Copy the temporary return value object to B. Ring 10 times.
Among them: 2.1 During the call f, if the Maximum parameter mode of F is not a biography, the COLL is called once a CONSTRUctor, 10 times in this example. Even if it is a bi-reference, because this reference is const, but must be a temporary TYPE object, or 10 times. 2.2 f The return value must be a transmission method, so f is returned once again to generate a temporary return value object, calling a Copy Constructor. Total 10 times. 2.3 Pass the return value of F to _ans, to call Type :: Operator = (), and 10 times.
That is to say, in order to give each 10 elements to 2 each multiply 2 b, the total will generate 10 10 10 10 = 40 temporary objects, and operator = () at least 20 times. Plus the operation of the destruction of the object, the additional overhead is quite large. Obviously, there is no use of cycles to assign a value.
(I am very confused for what apply () is unprusty to call the calling method of B.Apply (f, a), and write B = a.apply (f). If you use the previous method, you can save the generation of _ans, and The return value of the return value of _ans.) In addition, this form of apply () also limits the flexibility that does not need to pass parameters and do not need return values. For example 1. To make all members of A to be a random number, although it can write a F: INT F (INT / * NOT USED * /) {return rand ();} but write a = a . At the time of .Apply (f) is still a lot of waste. As another example, I want to output all the elements in A, then define f: int F (int 1) {cout << i << Endl; returnix i;} This can be executed with A.apply (f), but in which More return value processing is wasting ...
In summary: I think majray :: apply () is a very bad stuff from a micro. However, on the point of view of software engineering, it saves developers write a cycle of energy with excess 4 times loss. So I wrote this article purely the disease of the development era.
Gambolgs April 23, 2005