C ++ common template martial arts will be the first place: Vector v.s. list v.s. degue (on)

zhaozj2021-02-11  254

C common template martial arts will be the first place:

Vector v.s. list v.s. degue

Original author: beyond_ml

Ladies & Gentlem:

Hello everyone, here is the scene of the first C template martial arts meeting, this martial arts will be eastward by beyond_ml, the first nepon is beyond_ml. Because the first time the unprecedented event is held, it is inevitable that there is an omission, please also ask everyone to enlighten me. Beyond_ml is reasonable. At the same time, you will also welcome prawns to regard this martial arts as a virtual base class, constantly inherit, derived a new game.

Game start:

First introduce the contestants:

Vector: Jinshan Words Translated into: Vector, Vector, etc., the big brother in the C container template is like a strengthening queue, which is because it not only has the index of the queue, but also develops an expansion . Use especially in many classic textbooks in many classic textbooks.

Features: Store the object being included in the form of an array, supports access in the form of an index (which is very fast). However, there is also a problem, because the data storage form is fixed, if you want to be in the intermediate INSERT object, you will make you feel hard. Because he is assigning space, it is a continuous space assigned.

"Double-ended-queue" in English. Name, this is a famous two-way queue in the C ordered container. At the beginning of the design, he made special optimization for adding and deleting elements from both ends. Also supports access, also have a [] operator similar to the vector, but everyone should not mix him and vector to a pool.

Features: From essentially, he uses MAP structure and method when allocating memory. Tintered into zero, allocated many small continuous spaces, so it is very convenient to delete elements from both ends of Deque. The most important point: If you don't know if the memory is required, use Deque is definitely better than Vector, how is it well, and a certificate. In addition, inserting a sentence, I don't know if it is interested, in most cases, Deque and Vector are used interchangeably.

List: two-way linked list in the template. Designing his purpose may be to insert, delete it in the middle of the container, so there is no loss, his random access speed does not dare. And there is no [] operation. Even if you are in order from the order in the order, you don't see how much it will be fast.

Features: Random insertion, delete elements, accounts for a significant advantage at speeds. Also, because the memory allocation is discontinuous, his requirements for the insert are also very low. So when you use a big object, this is a good choice.

"Don't talk about leisure, start, start."

"咚 ..."

Fighting official start:

The first bureau: is more than one more memory management.

Method: Artificially caused storage of object data overflow, look at system consumption. System consumption here refers to: Object constructor, copy function, and sect number of call times.

The test procedure is as follows:

Noisy.h ... contains test objects, each time you call constructs, copy, and destructuring functions, you will print the corresponding prompts.

//: c04: noisy.h

// a class to track various object activity activities # ifndef noisy_h

#define noisy_h

#include

Class noisy

{

Static Long Create, Assign, Copycons, Destroy

Long id;

PUBLIC:

Noisy (): ID (Create )

{

Std :: cout << "D [" << ID << "]";

}

Noisy (const noisy & rv): id (rv.id)

{

Std :: cout << "C [" << ID << "]";

CopyCons ;

}

Noisy & Operator = (const noisy & rv)

{

Std :: cout << "(" << ID << ") = [" <<

RV.ID << "]";

ID = rv.id;

ASSIGN ;

RETURN * THIS;

}

Friend Bool

Operator <(Const Noisy & LV, Const Noisy & R)

{

Return lv.id

}

Friend Bool

Operator == (Const noisy & lv, const noisy & rv)

{

Return lv.id == rv.id;

}

~ Noisy ()

{

Std :: cout << "~ [" << ID << "]";

DESTROY ;

}

Friend Std :: Ostream &

Operator << (std :: ostream & os, const noisy&)

{

Return OS << n.id;

}

Friend class noisyreport;

}

Struct noisygen

{

Noisy operator () () {return noisy ();

}

// a singleton. Will Automatically Report Thae

// statistics as the program terminates:

Class noisyreport

{

Static noisyreport nr;

NoisyReport () {} // private constructor

PUBLIC:

~ Noisyreport ()

{

Std :: cout << "/ N ------------------ / N"

<< "Noisy Creations:" << Noisy :: Create

<< "/ ncopy-constructions:"

<< Noisy :: CopyCons

<< "/ nassignments:" << noisy :: assign

<< "/ ndestructions:" << noisy :: destroy

<< std :: endl;

}

}

// Because of these this file can only be used // in Simple Test Situations. Move THEM TO A

// .cpp file for more complex programs:

Long Noisy :: Create = 0, noisy :: assign = 0,

Noisy :: CopyCons = 0, noisy :: destroy = 0;

Noisyreport Noisyreport :: Nr;

#endif // noisy_h ///: ~

Target: Insert a thousand noisy objects.

Vector played

//: c04: Vectoroverflow.cpp

// shows the copy-construction and destruction

// That Occurs WHEN A Vector Must Reallocate

// (IT MAINTAINS a LINEAR ARRAY of Elements)

#include "noisy.h"

#include

#include

#include

#include

Using namespace std;

Int main (int Argc, char * argv [])

{

INT size = 1000;

IF (argc> = 2) size = atoi (Argv [1]);

VECTOR vn;

Noisy n;

For (int i = 0; i

VN.PUSH_BACK (N);

Cout << "/ n cleaning up / n";

} ///: ~

Test Results:

Noisy Creations: 1 (Constructor Call)

Copy-Constructions: 2023 (copy function call)

Assignments: 0 (assignment)

DESTRUCTIONS: 2024 (destructor call)

BEYOND_ML Comments: Wow! Boss, I just insert a thousand objects, how do you suddenly call 2023 copy functions, the corresponding 2024 episodes call,, it seems that if you inserted more than his retention space, Vector The movement of moving is very big.

Deque playing

The code section can look at the vector because they are too like.

Test Results:

NoiSy Creations: 1

Copy-Constructions: 1007

Assignments: 0

DESTRUCTIONS: 1008

BEYOND_ML Comments: Well, not bad. However, the seven of that come out is not very good.

List playing

The code part continues to copy.

Test Results:

NoiSy Creations: 1

Copy-Constructions: 1000

Assignments: 0

DESTRUCTIONS: 1001

BEYOND_ML Comments: Perfect! very good! Over.

The first game ends List win!

The second game is more than a random access (access speed is used as a clock cycle) How does the voice just fall? How does the List have a white flag? Oh, I remembered, he does not support random access strategy. That is, there is no [] and AT () operation.

Test procedure: indexingvsat.cpp Insert a thousand data, randomly accessed one million times with [] and AT (), compare clock cycles.

//: c04: indexingvsat.cpp

// comparing "at ()" to operator []

#include

#include

#include

#include

Using namespace std;

Int main (int Argc, char * argv [])

{

Long count = 1000;

INT SZ = 1000;

IF (argc> = 2) count = ATOI (Argv [1]);

IF (Argc> = 3) SZ = ATOI (Argv [2]);

Vector vi (sz);

Clock_t ticks = clock ();

For (int I1 = 0; I1

For (int J = 0; j

Vi [J];

COUT << "Vector [] << Clock () - Ticks << Endl;

Ticks = clock ();

For (int I2 = 0; i2

For (int J = 0; j

vi.at (j);

COUT << "Vector :: at ()" << Clock () - Ticks << Endl;

DEQUE di (sz);

Ticks = clock ();

For (int i3 = 0; i3

For (int J = 0; j

Di [J];

COUT << "Deque []" << clock () - ticks << endl;

Ticks = clock ();

For (int i4 = 0; i4

For (int J = 0; J

Di.at (j);

Cout << "Deque :: at () << Clock () - Ticks << endl;

// Demonstrate at () when you go out of bounds:

//di.at (vi.size () 1); error here.

} ///: ~

Test Results:

Vector [] 360000

Vector :: at () 790000

Deque [] 1350000

Deque :: at () 1750000

Beyond_ml Comments: Sure enough, don't know, a smile. Vector wins absolutely advantage!

The third game is higher than the rear insert and the speed of Iterator

The insertion method mainly uses Push_Back.

Then complete the operation of the data by the internal Iterator pointer. Test file:

Require.h mainly includes some file operations.

//:: Require.h

// Test for error conditions in programs

// local "Using Namespace Std" for Old Compilers

#ifndef required_h

#define require_h

#include

#include

#include

Inline Void Require (Bool Requirement, Const Char * MSG = "Requirement Failed")

{

Using namespace std;

IF (! request)

{

FPUTS (MSG, STDERR);

FPUTS ("/ n", stderr;

Exit (1);

}

}

Inline Void Requireargs (int Argc, int args, const char * msg = "must use% d arguments")

{

Using namespace std;

IF (argc! = args 1)

{

FPRINTF (stderr, msg, args);

FPUTS ("/ n", stderr;

Exit (1);

}

}

Inline Void Requireminargs (int Argc, int minArgs, const char * msg = "Must use at least% D arguments)

{

Using namespace std;

IF (argc

{

FPrintf (stderr, msg, minargs);

FPUTS ("/ n", stderr;

Exit (1);

}

}

Inline Void Assure (std :: ifstream & in, const char * filename = ")

{

Using namespace std;

IF (! in)

{

FPRINTF (stderr, "could not open file% s / n", filename);

Exit (1);

}

}

Inline Void Assure (std :: OFSTREAM & IN, Const char * filename = "")

{

Using namespace std;

IF (! in)

{

FPRINTF (stderr, "could not open file% s / n", filename);

Exit (1);

}

}

#ENDIF

StringDeque.cpp test main program

//: c04: Stringdeque.cpp

// converted from stringVector.cpp

#include "required" require.h "

#include

#include

#include

#include

#include

#include

#include

#include

#include

Using namespace std; int main (int Argc, char * argv [])

{

Requireargs (Argc, 1);

IFStream in (Argv [1]);

Assure (in, argv [1]);

Vector vStrings;

DEQUE DSTRINGS;

List lstrings;

String line;

// Time Reading Into Vector:

Clock_t ticks = clock ();

While (In, Line))

vstrings.push_back (line);

Ticks = clock () - ticks;

Cout << "Read Into Vector:" << Ticks << Endl;

// Repeat for Deque:

IFStream IN2 (Argv [1]);

Assure (IN2, Argv [1]);

Ticks = clock ();

While (getLine (in2, line))

DStrings.push_back (line);

Ticks = clock () - ticks;

Cout << "Read INTO Deque:" << Ticks << Endl;

// repeat for list:

IFStream IN3 (Argv [1]);

Assure (In3, ​​Argv [1]);

Ticks = clock ();

While (getLine (in3, line))

Lstrings.push_back (line);

Ticks = clock () - ticks;

COUT << "Read Into List: << Ticks << Endl;

// compare ity

OFSTREAM TMP1 ("TMP1.TMP"), TMP2 ("TMP2.TMP"), TMP3 ("TMP3.TMP");

Ticks = clock ();

Copy (vstrings.begin (), vstrings.end (),

ostream_iterator (TMP1, "/ N"))));

Ticks = clock () - ticks;

Cout << "ITERATING Vector:" << Ticks << endl;

Ticks = clock ();

Copy (dstrings.begin (), dstrings.end (),

Ostream_iterator (tmp2, "/ n"));

Ticks = clock () - ticks;

Cout << "ITERATING DEQEUE: << Ticks << endl;

Ticks = clock ();

Copy (lstrings.begin (), lstrings.end (),

Ostream_iterator (TMP3, "/ N"))));

Ticks = clock () - ticks;

COUT << "ITERATING LIST: << Ticks << Endl;

} ///: ~

The test used is a three thousand lines of text.

Test Results:

Read Into Vector: 690000

Read Into Deque: 680000

Read Into List: 690000

ITERATING Vector: 20000

ITERATING DEQEUE: 20000

ITERATING List: 10000

The file used by the test is a two thousand lines of text.

Read Into Vector: 460000

Read Into Deque: 460000

Read Into List: 440000

ITERATING Vector: 10000

ITERATING DEQEUE: 10000

ITERATING List: 20000

The test used is a thousand lines of text.

Test Results:

Read Into Vector: 230000

Read Into Deque: 240000

Read Into List: 250000

ITERATING Vector: 10000

ITERATING DEQEUE: 0

ITERATING List: 10000

BEYOND_ML comment: This is difficult, what do you say?

At the time of Push_Back, the smaller the file, the more you account for the Vector, the larger the file, the more you take it. Haha, joke, if you study, if you do, you don't do it. In fact, this is the result of the above test, the bigger the file, the more expensive, the reason is very simple, he wants Keeping new memory space to move yourself, and DEQUE is much better, because he doesn't have to move, he just needs a small rearrangement. And List is more problematic, his memory space is discrete. Can you understand this?

So as a function of the function itself is not big, but now it seems that if other factors are involved, it will be said.

At the point of view of reading data, the performance of List is very confused, I still can't think of any good explanation, maybe and the host's memory status when running. The performance of Vector and List can be said that it is not divided, but my personal point is that the vector must be better because his memory is continuous.

So the third game, the performance of the three has a thousand autumn.

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

New Post(0)