悪いコードが殺す

貧しいプログラマーであるジョンは、コードのミスを犯しました。そのため、プログラムの各ユーザーは、問題の回避策を探すために平均15分を費やす必要がありました。 1,000万人のユーザーがいました。 合計1億5000万分= 250万時間の無駄。 人が1日8時間眠る場合、意識的な活動のために16時間残ります。 つまり、ジョンは156250人日≈427.8人年を破壊しました。 平均的な男性は64歳なので、ジョンは人の約100分の68を殺しました。



ジョンはシリアルプログラマーですか?



ユーザーは食物連鎖の最下位です。 プログラマーもゆっくりと殺し合います。



良いコード規則



シンプルさ、明快さ、コンパクトさ、パフォーマンス、重複の欠如。



「hello world」よりも複雑なものを書く場合、1つではなく複数のファイルに配置されます。 原則として、ダース以上のファイルがあります。 それらのすべてには、理解できない短い名前が付けられています(プログラマーは略語を愛しています)あなたのコードを理解しようとする人は、あなたを吐き出し、ヒスし、呪います。 あなたのカルマはだめになり、次の数回の生活のためにあなたは韓国で犬になります。



注: 「hello world」は間違いではありません。LibreOfficeWriterが引用符を付ける方法です。 こんにちはジョニー いつもあなたに会えてうれしいです! 冗談です



良い名前を選ぶ方法



適切な名前はできるだけ短くしますが、オブジェクトの本質を正確に反映します。 人々はあなたのコード(そしてあなた自身も就寝前に)を読むので、名前は人々にはっきりとわかるはずです。



John_poor_programmerは良い名前です。 適切な名前は、1、2、または3つの単語で構成されます。 3つはたくさんあります。 1つは良いですが、多くの場合、本質を反映するには不十分です。 次のファイル名(クラス)を読んでください。内部を見ずにコードの目的を推測できますか?



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();
	}
};
      
      






All Articles