📜 âŹ†ïž âŹ‡ïž

Bad code kills

Bad programmer John made a mistake in the code, due to which each user of the program was forced to spend an average of 15 minutes of time searching for a workaround for the problem. There were 10 million users. Total wasted 150 million minutes = 2.5 million hours. If a person sleeps 8 hours a day, then he will have 16 hours left for conscious activity. That is, John destroyed 1,56250 person-days ≈ 427.8 person-years. The average man lives 64 years, so John killed about 6 point 68 hundredths of a person.

How do you sleep, John is a serial programmer?

Users - the bottom of the food chain. Programmers also slowly kill each other.
')

Good Code Rules


Simplicity-clarity-compactness, performance, no duplication.

If you write something harder than “hello world”, it will be placed not in one, but in several files. As a rule, there are more than a dozen files. All of them are given incomprehensible short names (programmers love abbreviations). A person who tries to understand your code will spit, hiss, and curse you. Your karma will be spoiled and the next few lives you will be a dog in Korea.

Note: “hello world” is not an error, this is exactly the way LibreOffice Writer quotes it. Hello johnny Always glad to see you! Just kidding, never.

How to choose a good name


A good name is as short as possible, but it also reflects the essence of the object as accurately as possible. Your code will be read by people (and you yourself before bedtime), so the names should be clear to people.

John_Borser_Programmer is a good name. A good name consists of one, two or three words. Three is a lot. One thing is good, but often not enough to reflect the essence. Read the following file (class) names, can you guess the purpose of the code without looking inside?

profiler.h
jitter_measurement.h
developer_menu.h
Animation2D.h
Rectangle.h
Wind_effect.h

. .

SoMFVec2s.h, . , .

: 8.3 20 .

?


.

.

« » . 20NN .

— — . std:: cv:: . !

?
- ?
.
. , .
100 ? ? 



.

int i;
char c;
byte b;
string s;
vector v;
pointer p;
argument a1;

, , . , - -. - — , .


« windows», « windows», « windows» « windows». , . , : , .

52 , . : « » . .

. , , , , , . , , 5 . , .


, . , . .

...



. , , . . . — . ! !

, , ! !

6 , . 6 ! , ! !

, . . , remote code execution ! ! 100% .

. KB3136000 .

, !

!


20. : . :

void split(const string& s, std::vector<string>& result, const string& delimiters = " ")
{
	string::size_type a = s.find_first_not_of(delimiters, 0);
	string::size_type b = s.find_first_of(delimiters, a);

	while (string::npos != b || string::npos != a)
	{
		result.push_back(s.substr(a, b - a));

		a = s.find_first_not_of(delimiters, b);
		b = s.find_first_of(delimiters, a);
	}
}

, :

void split(const string& s, std::vector<string>& result, const string& delimiters = " ")
{
	string::size_type a, b = 0;

	for(;;)
	{	a = s.find_first_not_of(delimiters, b);
		b = s.find_first_of(delimiters, a);

		if (string::npos == b && string::npos == a) break;

		result.push_back(s.substr(a, b - a));
	}
}

— . : boost, , , 
 boost, SSD , 
 « - ...»

, ! ? , . . - . , , . 


, C++ ? , ?


, « » — . . , , 


, , :

unsigned long t0 = current_time();
// - 

cout << current_time() - t0 << endl;

, 10 , .

profiler.h
/*
Profiler prof;

for (;;)
{
	Sleep(50); // code, which does not need to measure performance

	prof(NULL);

	Sleep(100); // some code

	prof("code1");

	Sleep(200); // some code

	prof("code2");

	prof.periodic_dump(5);
		// every 5 seconds will print table
}
*/

#include <stdint.h>
#include <stdio.h>

#include <string>
using std::string;

#include <set>
using std::set;

#include <algorithm>
using std::min;
using std::max;

#ifdef WIN32
#include <Windows.h>

class Microseconds
{
public:
	uint64_t operator()()
	{
		LARGE_INTEGER now;
		QueryPerformanceCounter(&now);
		LARGE_INTEGER freq;
		QueryPerformanceFrequency(&freq);

		return now.QuadPart * 1000 / (freq.QuadPart / 1000);
			// overflow occurs much later
	}
};

#else
#include <sys/time.h>
//#include "android_workarround.h"
class Microseconds
{
public:
	uint64_t operator()()
	{
		timeval tv;
		gettimeofday(&tv, NULL);
		return (uint64_t)tv.tv_sec * 1000000 + tv.tv_usec;
	}
};
#endif

class Profiler
{
	Microseconds microseconds;

	class Event
	{
		public:
		const char* name;
		uint64_t time;
		uint64_t count;
		uint64_t min_time;
		uint64_t max_time;

		void reset()
		{
			time = 0;
			count = 0;
			min_time = (uint64_t)-1;
			max_time = 0;
		}
	};

	class Comparator
	{
		public:
		bool operator()(const Event& a, const Event& b) const
		{	//return strcmp(a.name, b.name) < 0;
			return (void*)a.name < (void*)b.name;
		}
	};

	set<Event, Comparator> events;

	uint64_t t0;
	uint64_t last_dump;

	Event c;
	set<Event>::iterator i;

public:
	Profiler()
	{
		last_dump = t0 = microseconds();
	}

	void operator()(const char* what)
	{
		if (what == NULL)
		{
			t0 = microseconds();
			return;
		}

		uint64_t t = microseconds() - t0;

		c.name = what;
		i = events.find(c);

		if (i == events.end())
		{
			c.reset();
			i = events.insert(c).first;
		}

		Event& e = const_cast<Event&>(*i);

		e.time += t;
		e.min_time = min(e.min_time, t);
		e.max_time = max(e.max_time, t);
		++e.count;

		t0 = microseconds();
	}

	void dump()
	{
		const float MS = 0.001f;

		float f_summ = 0;
		for (i = events.begin(); i != events.end(); ++i)
			f_summ += (float)i->time;

		if (f_summ == 0) return;

		f_summ *= MS;
		f_summ *= .01f; // %

		printf("           name count   total(%%)        min   avg   max\n");

		for (i = events.begin(); i != events.end(); ++i)
		{
			Event& e = const_cast<Event&>(*i);

			if (e.count == 0) e.min_time = 0;

			float f_time = e.time * MS;
			float f_min = e.min_time * MS;
			float f_max = e.max_time * MS;
			float f_average = e.count == 0 ? 0 : f_time / (float)e.count;

			printf("%15s %5llu %7.1f(%5.1f%%) %5.1f %5.1f %5.1f\n",
				e.name, (long long unsigned int)e.count,
				f_time, f_time / f_summ, f_min, f_average, f_max);

			e.reset();
		}
	}

	void periodic_dump(unsigned int period)
	{
		if (microseconds() < last_dump + period * 1000000) return;
		dump();
		last_dump = microseconds();
	}
};

, :

           name count   total(%)        min   avg   max 
       detector     0     0.0(  0.0%)   0.0   0.0   0.0 
      predictor   161   287.8( 46.1%)   1.0   1.8   2.3 
        refiner   161   246.9( 39.5%)   0.8   1.5   1.8 
      shape fit   161    90.0( 14.4%)   0.3   0.6   0.8 

, .

, dump , vector out; . . , ? . .

- . — . , 500 , , .


, « » , « », . , .

, . ? . ? . — .


, ! . ? , ? , ? « . , », ? , 
 -
 . .

— .
— .
— .
— .
— .
— .


windows, 15 . 5048 


profiler.h

profiler.h
/*

#ifdef linux
#include <time.h>
void Sleep(int milliseconds)
{
	struct timespec ts;
	ts.tv_sec = milliseconds / 1000;
	ts.tv_nsec = (milliseconds % 1000) * 1000000;
	nanosleep(&ts, NULL);
}
#endif

int main()
{	Profiler prof;

	for(;;)
	{	
		Sleep(50); // code, which does not need to measure performance

		prof(NULL);

		Sleep(100); // some code

		prof("code1");

		Sleep(200); // some code

		prof("code2");

		prof.periodic_dump(5);
			// every 5 seconds will print table
	}
	return 0;
}
*/

#include <stdint.h>
#include <stdio.h>

#include <vector>
using std::vector;

#include <string>
using std::string;

#include <map>
using std::map;

#include <algorithm>
using std::min;
using std::max;

#include <utility>
using std::make_pair;

#include <iostream>
using std::cout;

#ifdef linux

#include <sys/time.h>

static uint64_t microseconds()
{	timeval tv;
	gettimeofday(&tv, NULL);
	return (uint64_t)tv.tv_sec * 1000000 + tv.tv_usec;
}

#else

#include <Windows.h>

static uint64_t microseconds()
{
	LARGE_INTEGER now;
	QueryPerformanceCounter(&now);
	LARGE_INTEGER freq;
	QueryPerformanceFrequency(&freq);
	return now.QuadPart * 1000 / (freq.QuadPart / 1000);
		// overflow occurs much later
}

#endif

class Profiler
{	
	class Event
	{
	public:
		uint64_t time;
		uint64_t count;
		uint64_t min_time;
		uint64_t max_time;

		void reset()
		{	time = 0;
			count = 0;
			min_time = (uint64_t)-1;
			max_time = 0;
		}
	};

	map<const char*, Event> events;

	uint64_t t0;
	uint64_t last_dump;

	map<const char*, Event>::iterator i;

public:
	vector<string> out;

	Profiler()
	{	last_dump = t0 = microseconds();
	}

	void operator()(const char* what)
	{	
		if (what == NULL)
		{
			t0 = microseconds();
			return;
		}
		
		uint64_t t = microseconds() - t0;

		i = events.find(what);
		
		if(i == events.end())
		{	
			Event e;
			e.reset();
			i = events.insert(make_pair(what, e)).first;
		}

		Event& e = (*i).second;

		e.time += t;
		e.min_time = min(e.min_time, t);
		e.max_time = max(e.max_time, t);
		++e.count;

		t0 = microseconds();
	}

	void dump()
	{
		out.clear();

		const float us_to_ms = 0.001f;
		
		float summ = 0;
		for (i = events.begin(); i != events.end(); ++i)
		{	
			Event& e = (*i).second;

			summ += (float)e.time;
		}

		if (summ == 0) return;

		summ *= us_to_ms;

		out.push_back("           name count   total(%)        min   avg   max\n");

		for(i = events.begin(); i != events.end(); ++i)
		{
			Event& e = (*i).second;

			if(e.count == 0) e.min_time = 0;

			float time = e.time * us_to_ms;
			float min_time = e.min_time * us_to_ms;
			float max_time = e.max_time * us_to_ms;
			float average = e.count == 0 ? 0 : time / (float)e.count;

			char tmp[0x100];

			snprintf(tmp, sizeof(tmp), "%15s %5llu %7.1f(%5.1f%%) %5.1f %5.1f %5.1f\n",
				i->first, (long long unsigned int)e.count,
				time, time / summ * 100, min_time, average, max_time);
			out.push_back(tmp);
			
			e.reset();
		}

		for (int i = 0; i < out.size(); ++i) cout << out[i];
	}

	void periodic_dump(unsigned int period)
	{	if(microseconds() < last_dump + period * 1000000) return;
		dump();
		last_dump = microseconds();
	}
};

Source: https://habr.com/ru/post/309388/


All Articles