Valarray :: Apply () Critique

xiaoxiao2021-03-05  22

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 a (10); Valarray B (10);

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 , and find that this apply () is:

Valarray <_ty> Apply (_ty, size ()); _f (_ptr [_i]));} #define _valop (Type, Length, RHS) / Valarray _ans (Length " ); / For (size_t _i = 0; _i <_ans.size (); _ i) / _ans [_i] = rhs; / return (_ans)

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

转载请注明原文地址:https://www.9cbs.com/read-32598.html

New Post(0)