{"id":260179,"date":"2015-06-26T13:59:02","date_gmt":"2015-06-26T09:59:02","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=260179"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=260179","title":{"rendered":"\u0421\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u044f\u0437\u044b\u043a\u043e\u0432 \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043f\u0440\u043e\u0441\u0442\u0435\u0439\u0448\u0435\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430"},"content":{"rendered":"<p>     \t\u0414\u043e\u0431\u0440\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441\u0443\u0442\u043e\u043a, \u0445\u0430\u0431\u0440!<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/d80\/6c9\/61a\/d806c961a07d4ebfaeda1dbf56a621fa.png\" align=\"left\"\/><br \/>  \u041c\u043e\u0438\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u043c \u042f\u041f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f D. \u0412\u0441\u0435\u0433\u0434\u0430 \u043f\u043e\u043d\u0438\u043c\u0430\u043b, \u0447\u0442\u043e \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0438\u0433\u0440\u044b\u0432\u0430\u0442\u044c C++ \u0438\u0437-\u0437\u0430 \u0441\u0431\u043e\u0440\u0449\u0438\u043a\u0430, \u043a\u0430\u043a\u0438\u0445-\u0442\u043e \u0432\u044b\u0441\u043e\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u0445 \u043f\u043b\u044e\u0448\u0435\u043a \u0438 \u0442.\u0434. \u041d\u043e \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0434\u043e\u0445\u043e\u0434\u0438\u043b\u0438 \u0440\u0443\u043a\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e. \u0420\u0435\u0448\u0438\u043b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u0435\u043d\u044c\u043a\u0438\u0439 \u043a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 (\u0434\u0430\u0436\u0435 \u043d\u0435 \u043f\u043e\u043c\u043d\u044e \u043c\u0435\u0442\u043e\u0434 \u043a\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f) \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c. \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043c\u0435\u043d\u044f \u043f\u0440\u0438\u044f\u0442\u043d\u043e \u0443\u0434\u0438\u0432\u0438\u043b: \u0432\u0435\u0440\u0441\u0438\u044f C++ \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0430 \u0437\u0430 5.47 \u0441\u0435\u043a, \u0432\u0435\u0440\u0441\u0438\u044f D \u2014 \u0437\u0430 5.55 \u0441\u0435\u043a. \u00ab0.08 \u0441\u0435\u043a \u043f\u0440\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0444\u0430\u0439\u043b\u0430 \u0432 74\u041c\u0431 \u044d\u0442\u043e \u043d\u0435 \u0442\u0430\u043a \u0443\u0436 \u0438 \u043c\u043d\u043e\u0433\u043e\u00bb \u2014 \u043f\u043e\u0434\u0443\u043c\u0430\u043b \u044f. \u041d\u043e, \u043d\u0430 \u0432\u0441\u044f\u043a\u0438\u0439 \u0441\u043b\u0443\u0447\u0430\u0439, \u0440\u0435\u0448\u0438\u043b \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u043a\u043e\u0434 \u043d\u0430 D \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e gdc (dmd \u043a\u0430\u043a frontend, gnu backend) \u0438 \u0442\u0443\u0442 \u0443\u0436\u0435 \u0432 \u0434\u0443\u0448\u0443 \u0437\u0430\u043a\u0440\u0430\u043b\u0438\u0441\u044c \u0441\u043e\u043c\u043d\u0435\u043d\u0438\u044f, \u0447\u0442\u043e \u044f \u0432\u0441\u0451 \u0441\u0434\u0435\u043b\u0430\u043b \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e: \u043a\u043e\u0434 \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0437\u0430 4.01 \u0441\u0435\u043a, \u0447\u0442\u043e \u0431\u043e\u043b\u0435\u0435 \u0447\u0435\u043c \u043d\u0430 20% \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0432\u0435\u0440\u0441\u0438\u0438 \u043d\u0430 \u0421++. \u0420\u0435\u0448\u0438\u043b \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e ldc2 (dmd frontend, llvm backend): 2.92(!!) \u0441\u0435\u043a. \u0422\u0443\u0442 \u044f \u0440\u0435\u0448\u0438\u043b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f.<br \/>  <a name=\"habracut\"><\/a><br \/>  \u041f\u0440\u0435\u0432\u044b\u043c \u0434\u0435\u043b\u043e\u043c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b valgrind &#8212;tool=callgrind \u0434\u043b\u044f C++ \u0432\u0435\u0440\u0441\u0438\u0438. \u041a\u0430\u043a \u0438 \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043b\u043e \u043e\u0436\u0438\u0434\u0430\u0442\u044c \u043d\u0430 \u0447\u0442\u0435\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u0430 \u0443\u0445\u043e\u0434\u0438\u0442 \u0431\u041e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0432\u0440\u0435\u043c\u0435\u043d\u0438.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/c40\/fce\/e12\/c40fcee1214b47fb807b7b45dbeea0b5.png\"\/><\/p>\n<p>  \u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0432\u0435\u0440\u0441\u0438\u0438 dmd valgrind \u043d\u0435 \u0441\u043c\u043e\u0433 \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c, \u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0441\u044f \u043e\u0448\u0438\u0431\u043a\u043e\u0439 illegal hardware instruction, \u0432\u0438\u0434\u0438\u043c\u043e \u0440\u0435\u0431\u044f\u0442\u0430 \u0438\u0437 DigitalMars \u043d\u0430\u043a\u043e\u043b\u0434\u043e\u0432\u0430\u043b\u0438 \u0441 \u0430\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u043e\u043c \u0441\u0438\u043b\u044c\u043d\u043e, \u043d\u043e \u0434\u043b\u044f gdc \u0438 ldc2 \u0432\u0441\u0451 \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e, \u043a\u0430\u043a \u0434\u043b\u044f \u0432\u0435\u0440\u0441\u0438\u0438 \u0421++.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/2cd\/a2d\/4cb\/2cda2d4cbfb34e87afdfd9a74f1b6ba1.png\"\/><\/p>\n<p>  \u0425\u043e\u0442\u044c \u0438 valgrind \u043d\u0435 demangle&#8217;\u0438\u0442 \u0438\u043c\u0435\u043d\u0430 D \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u0437\u0430\u0442\u043e \u0435\u0441\u0442\u044c \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0439 \u0445\u0430\u043a: callgrind.out.NNN \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0447\u0435\u0440\u0435\u0437 <a href=\"https:\/\/github.com\/D-Programming-Language\/tools\/blob\/master\/ddemangle.d\">\u044d\u0442\u043e\u0442<\/a> \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u044b\u0435 \u0438\u043c\u0435\u043d\u0430 (\u043d\u0435 \u0432\u0441\u0435, \u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0443\u044e \u0447\u0430\u0441\u0442\u044c). \u0418 <a href=\"http:\/\/habrahabr.ru\/post\/260151\/#comment_8458343\">\u043f\u0440\u043e\u0448\u0443 \u043f\u0440\u043e\u0449\u0435\u043d\u0438\u044f \u0437\u0430 gdb<\/a>, \u0432\u0435\u0440\u0441\u0438\u044f 7.9.1-13.fc22 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 demangle D \u043a\u043e\u0434\u0430.<\/p>\n<p>  \u041e\u0441\u043e\u0437\u043d\u0430\u043b \u044f, \u0447\u0442\u043e \u0440\u0430\u043d\u043e \u0440\u0430\u0434\u043e\u0432\u0430\u0442\u044c\u0441\u044f, \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u044f\u0441\u043d\u0438\u0442\u044c \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430. \u0418 \u0440\u0430\u0437 \u0443\u0436 \u043d\u0430 \u0442\u043e \u043f\u043e\u0448\u043b\u043e, \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430:  <\/p>\n<ol>\n<li>\u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u2014 \u0441\u043e\u0437\u0434\u0430\u044e\u0442\u0441\u044f \u043a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b, \u0442\u043e\u0447\u043a\u0438 \u0432 \u043a\u043b\u0430\u0441\u0441\u0430\u0445 \u043d\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u044e\u0442\u0441\u044f<\/li>\n<li>\u0441 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435\u043c \u0442\u043e\u0447\u0435\u043a \u0438 \u0441\u043b\u0438\u044f\u043d\u0438\u0435\u043c \u043a\u043b\u0430\u0441\u0441\u043e\u0432 (\u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0441 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u043e\u0439 \u043f\u043b\u043e\u0434\u0438\u043b \u043c\u043d\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u043e\u0432)<\/li>\n<\/ol>\n<p>  \u041f\u0430\u0440\u0430 \u0441\u043b\u043e\u0432 \u043f\u043e \u043f\u043e\u0432\u043e\u0434\u0443 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430: \u044f \u043d\u0435 \u0441\u0442\u0430\u0432\u0438\u043b \u0437\u0430\u0434\u0430\u0447\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0445\u043e\u0440\u043e\u0448\u0438\u0439 \u043a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0435\u0433\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c, \u043f\u0440\u043e\u0441\u0442\u043e \u0442\u0435\u0441\u0442\u043e\u0432\u044b\u0439 \u043a\u043e\u0434.<br \/>  \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0430\u0445, \u0432 \u0441\u043a\u043e\u0431\u043e\u0447\u043a\u0430\u0445 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 \u043a \u0421++ \u043a\u043e\u0434\u0443:  <\/p>\n<table>\n<tr>\n<th><\/th>\n<th>c++ g++<\/th>\n<th>d dmd<\/th>\n<th>d gdc<\/th>\n<th>d ldc2<\/th>\n<\/tr>\n<tr>\n<td>1<\/td>\n<td>0.577<\/td>\n<td>1.797 (3.11)<\/td>\n<td>0.999 (1.73)<\/td>\n<td>0.583 (1.01)<\/td>\n<\/tr>\n<tr>\n<td>2<\/td>\n<td>0.628<\/td>\n<td>2.272 (3.617)<\/td>\n<td>1.217 (1.937)<\/td>\n<td>0.898 (1.429)<\/td>\n<\/tr>\n<\/table>\n<p>  \u0412\u0442\u043e\u0440\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u0430\u043a\u0442\u0438\u0432\u043d\u0435\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0441\u0431\u043e\u0440\u0449\u0438\u043a \u043c\u0443\u0441\u043e\u0440\u0430 (\u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u043d\u0438\u043a\u0430\u043a \u043d\u0435 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u043b). \u041b\u0443\u0447\u0448\u0438\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u0434\u0430\u043b, \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0436\u0435, ldc2 \u2014 \u0432 \u043f\u043e\u043b\u0442\u043e\u0440\u0430 \u0440\u0430\u0437\u0430 \u043c\u0435\u0434\u043b\u0435\u043d\u0435\u0439 \u0421++ \u043f\u0440\u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0439 \u0441\u0431\u043e\u0440\u043a\u0435 \u043c\u0443\u0441\u043e\u0440\u0430, \u0447\u0442\u043e, \u0432 \u0438\u0442\u043e\u0433\u0435, \u043d\u0435 \u0442\u0430\u043a \u0443\u0436 \u0438 \u043f\u043b\u043e\u0445\u043e. \u0418 \u0434\u0430\u0436\u0435 \u043e\u0447\u0435\u043d\u044c \u0445\u043e\u0440\u043e\u0448\u043e, \u0435\u0441\u043b\u0438 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c \u043f\u043e\u043b\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b (5.4 \u0441\u0435\u043a \u0434\u043b\u044f C++ \u043f\u0440\u043e\u0442\u0438\u0432 2.9 \u0441\u0435\u043a \u0434\u043b\u044f D \u043d\u0430 ldc2).<\/p>\n<p>  \u0415\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0434\u043b\u044f \u0447\u0438\u0441\u0442\u043e\u0442\u044b \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0430, \u043a\u043e\u0434 \u044f \u043d\u0438\u043a\u0430\u043a \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u043d\u0435 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043b \u0438 \u0441\u0434\u0435\u043b\u0430\u043b \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u044d\u043a\u0432\u0438\u0432\u0430\u043b\u0435\u043d\u0442\u043d\u044b\u043c.  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041a\u043e\u0434 \u043d\u0430 D<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code>import std.stdio; import std.math; import std.format; import std.datetime;  \/\/version=COLLECT_MEASURES; \/\/version=MERGE_CLASSES;  struct Measure {     float x=0, y=0;      auto opBinary(string op)( auto ref const Measure m ) const         if( op == &quot;+&quot; || op == &quot;-&quot; )     { mixin( &quot;return Measure( x &quot; ~ op ~ &quot; m.x, y &quot; ~ op ~ &quot; m.y );&quot; ); }      auto opBinary(string op)( float m ) const         if( op == &quot;*&quot; || op == &quot;\/&quot; )     { mixin( &quot;return Measure( x &quot; ~ op ~ &quot; m, y &quot; ~ op ~ &quot; m );&quot; ); } }  unittest {     auto a = Measure(1,3);     auto b = Measure(4,5);     auto add = a + b;     assert( add.x == 5 && add.y == 8 );     auto dif = a - b;     assert( dif.x == -3 && dif.y == -2 );     auto mlt = a * 3;     assert( mlt.x == 3 && mlt.y == 9 );     auto div = b \/ 2;     assert( div.x == 2 && div.y == 2.5 ); }  float sqr( float v ) { return v * v; }  float dist( ref const Measure a, ref const Measure b ) { return sqrt( sqr(a.x - b.x) + sqr(a.y - b.y) ); }  class Class {     Measure mean;     size_t N;     version(COLLECT_MEASURES)         Measure[] measures;      this( in Measure m )     {         mean = m;         N = 1;         version(COLLECT_MEASURES)             measures ~= m;     }      void append( in Measure m )     {         mean = ( mean * N + m ) \/ ( N + 1 );         N++;         version(COLLECT_MEASURES)             measures ~= m;     }      void merge( const Class m )     {         mean = ( mean * N + m.mean * m.N ) \/ ( N + m.N );         N += m.N;         version(COLLECT_MEASURES)             measures ~= m.measures;     } }  unittest {     auto cls = new Class( Measure(1,2) );     assert( cls.mean.x == 1 && cls.mean.y == 2 );     assert( cls.N == 1 );     cls.append( Measure(3,4) );     assert( cls.mean.x == 2 && cls.mean.y == 3 );     assert( cls.N == 2 ); }  class Classifier { public:     Class[] list;     float ncls_dist;      this( float mdist ) { ncls_dist = mdist; }      void classificate( ref const Measure m )     {         float min_dist = float.max;         Class near_cls;          foreach( i; list )         {             float d = dist( m, i.mean );             if( d &lt; min_dist )             {                 min_dist = d;                 near_cls = i;             }         }          if( min_dist &lt; ncls_dist ) near_cls.append(m);         else list ~= new Class(m);     }      void mergeClasses()     {         Class[] uniq;          l: foreach( cls; list )         {             foreach( trg; uniq )                 if( dist( cls.mean, trg.mean ) &lt; ncls_dist )                 {                     trg.merge( cls );                     continue l;                 }              uniq ~= cls;         }          list = uniq;     } }  Measure[] readMeasuresFromFile( string name ) {     auto file = File( name, &quot;r&quot; );     Measure[] list;      foreach( line; file.byLine() )     {         Measure tmp;         formattedRead( line, &quot;%f %f&quot;, &tmp.x, &tmp.y );         list ~= tmp;     }      return list; }  void main( string[] args ) {     auto measures = readMeasuresFromFile( args[1] );      StopWatch sw;      sw.start();      auto clsf = new Classifier(3);      foreach( m; measures )         clsf.classificate(m);      version(MERGE_CLASSES)         clsf.mergeClasses();      sw.stop();      writeln( &quot;work time: &quot;, sw.peek.nsecs \/ 1_000_000_000.0f );      foreach( cls; clsf.list )         writefln( &quot;[%f, %f]: %d&quot;, cls.mean.x, cls.mean.y, cls.N ); } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041a\u043e\u0434 \u043d\u0430 \u0421++<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code>#include &lt;vector&gt; #include &lt;cmath&gt; #include &lt;cfloat&gt; #include &lt;iostream&gt; #include &lt;fstream&gt; #include &lt;sstream&gt; #include &lt;string&gt; #include &lt;cassert&gt; #include &lt;ctime&gt;  using namespace std;  \/\/#define COLLECT_MEASURES \/\/#define MERGE_CLASSES  class Measure { public:     float x, y;      Measure(): x(0), y(0) {}     Measure( float X, float Y ): x(X), y(Y) {}     Measure( const Measure& m ): x(m.x), y(m.y) {}      Measure operator+( const Measure& m ) const     { return Measure( x + m.x, y + m.y ); }      Measure operator-( const Measure& m ) const     { return Measure( x - m.x, y - m.y ); }      Measure operator*( float v ) const     { return Measure( x * v, y * v ); }      Measure operator\/( float v ) const     { return Measure( x \/ v, y \/ v ); } };  void test_Measure() {     Measure a(1,3);     Measure b(4,5);     auto add = a + b;     assert( add.x == 5 && add.y == 8 );     auto dif = a - b;     assert( dif.x == -3 && dif.y == -2 );     auto mlt = a * 3;     assert( mlt.x == 3 && mlt.y == 9 );     auto div = b \/ 2;     assert( div.x == 2 && div.y == 2.5 ); }  inline float sqr( float v ) { return v * v; }  float dist( const Measure& a, const Measure& b ) { return sqrt( sqr(a.x - b.x) + sqr(a.y - b.y) ); }  class Class { public:     Measure mean;     size_t N;     #ifdef COLLECT_MEASURES     vector&lt;Measure&gt; measures;     #endif      Class( const Measure& m ): mean(m)     {         N = 1;         #ifdef COLLECT_MEASURES         measures.push_back(m);         #endif     }      void append( const Measure& m )     {         mean = ( mean * N + m ) \/ ( N + 1 );         N++;         #ifdef COLLECT_MEASURES         measures.push_back(m);         #endif     }      void merge( const Class& m )     {         mean = ( mean * N + m.mean * m.N ) \/ ( N + m.N );         N += m.N;         #ifdef COLLECT_MEASURES         measures.insert(measures.end(), m.measures.begin(), m.measures.end());         #endif     } };  void test_Class() {     auto cls = Class( Measure(1,2) );     assert( cls.mean.x == 1 && cls.mean.y == 2 );     assert( cls.N == 1 );     cls.append( Measure(3,4) );     assert( cls.mean.x == 2 && cls.mean.y == 3 );     assert( cls.N == 2 ); }  class Classifier { public:     vector&lt;Class*&gt; list;     float ncls_dist;      Classifier( float mdist ): ncls_dist(mdist) {}      void classificate( const Measure& m )     {         float min_dist = FLT_MAX;         Class* near_cls;          for( auto i = list.begin(); i != list.end(); ++i )         {             float d = dist( m, (*i)-&gt;mean );             if( d &lt; min_dist )             {                 min_dist = d;                 near_cls = *i;             }         }          if( min_dist &lt; ncls_dist ) near_cls-&gt;append(m);         else list.push_back( new Class(m) );     }      void mergeClasses()     {         vector&lt;Class*&gt; uniq;          l: for( auto cls = list.begin(); cls != list.end(); ++cls )         {             bool is_uniq = true;             for( auto trg = uniq.begin(); trg != uniq.end(); ++trg )             {                 if( dist( (*cls)-&gt;mean, (*trg)-&gt;mean ) &lt; ncls_dist )                 {                     (*trg)-&gt;merge( **cls );                     delete (*cls);                     is_uniq = false;                 }                 if( !is_uniq ) break;             }              if( is_uniq ) uniq.push_back( *cls );         }          list = uniq;     }      ~Classifier()     {         for( auto i = list.begin(); i != list.end(); ++i )             delete *i;     } };  vector&lt;Measure&gt; readMeasuresFromFile( char* name ) {     ifstream file( name );     vector&lt;Measure&gt; list;      for( string line; getline(file, line); )     {         istringstream in( line );         Measure tmp;         in &gt;&gt; tmp.x &gt;&gt; tmp.y;         list.push_back( tmp );     }      return list; }  void runTests() {     test_Measure();     test_Class(); }  int main( int argc, char* args[] ) {     \/\/runTests();      auto measures = readMeasuresFromFile( args[1] );      clock_t start = clock();      auto clsf = new Classifier(3);      for( auto i = measures.begin(); i != measures.end(); ++i )         clsf-&gt;classificate( *i );      #ifdef MERGE_CLASSES     clsf-&gt;mergeClasses();     #endif      clock_t end = clock();      cout &lt;&lt; &quot;work time: &quot; &lt;&lt; double(end - start) \/ CLOCKS_PER_SEC &lt;&lt; endl;      for( auto i = clsf-&gt;list.begin(); i != clsf-&gt;list.end(); ++i )         cout &lt;&lt; &quot;[&quot; &lt;&lt; (*i)-&gt;mean.x &lt;&lt; &quot;, &quot; &lt;&lt; (*i)-&gt;mean.y &lt;&lt; &quot;]: &quot; &lt;&lt; (*i)-&gt;N &lt;&lt; endl;      delete clsf; } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041a\u043e\u0434 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u0432\u044b\u0431\u043e\u0440\u043a\u0438<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code>import std.stdio; import std.string; import std.exception; import std.random; import std.math;  double normal( double mu=0.0, double sigma=1.0 ) {     static bool deviate = false;     static float stored;      if( !deviate )     {         double max = cast(double)(ulong.max - 1);         double dist = sqrt( -2.0 * log( uniform( 0, max ) \/ max ) );         double angle = 2.0 * PI * ( uniform( 0, max ) \/ max );          stored = dist * cos( angle );         deviate = true;          return dist * sin( angle ) * sigma + mu;     }     else     {         deviate = false;         return stored * sigma + mu;     } }  struct vec { float x, y; }  vec randomVec( in vec m, in vec s ) { return vec( normal(m.x, s.x), normal(m.y, s.y) ); }  auto generate( size_t[vec] classes ) {     vec[] ret;     foreach( pnt, count; classes )     {         auto tmp = new vec[]( count );         foreach( i, ref t; tmp )             t = randomVec( pnt, vec(1,1) );         ret ~= tmp;     }     return ret; }  import std.getopt;  void main( string[] args ) {     uint k;      getopt( args,              &quot;count-multiplier|c&quot;, &k           );      enforce( args.length == 2, format( &quot;wrong number of arguments: use %s &lt;output_file&gt;&quot;, args[0] ) );      auto f = File( args[1], &quot;w&quot; );     scope(exit) f.close();      auto vs = generate( [ vec(-8,8): 20 * k, vec(4,0) : 10 * k, vec(-6,-8) : 15 * k ] );      foreach( v; vs.randomSample(vs.length) )         f.writeln( v.x, &quot; &quot;, v.y ); } <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0421\u0431\u043e\u0440\u043a\u0430<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"bash\">g++ -O2 -std=c++11 cls.cpp -o cls_cpp && echo &quot;c++ g++ builded&quot; dmd -O -release cls.d -ofcls_d_dmd && echo &quot;d dmd builded&quot; ldc2 -O2 -release cls.d -ofcls_d_ldc2 && echo &quot;d ldc2 builded&quot; gdc -O2 cls.d -o cls_d_gdc && echo &quot;d gdc builded&quot; <\/code><\/pre>\n<p>  <\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0412\u0435\u0440\u0441\u0438\u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u043e\u0432<\/b><\/p>\n<div class=\"spoiler_text\">g++ (GCC) 5.1.1 20150612 (Red Hat 5.1.1-3)<br \/>  DMD64 D Compiler v2.067.1<br \/>  GNU gdb (GDB) Fedora 7.9.1-13.fc22<br \/>  LDC \u2014 the LLVM D compiler (0.15.2-beta1)  <\/div>\n<\/div>\n<p>  PS. \u0412 \u044f\u0437\u044b\u043a\u0430\u0445 Rust \u0438 Go \u043d\u0435 \u0441\u0438\u043b\u0451\u043d, \u0435\u0441\u043b\u0438 \u043a\u0442\u043e-\u043d\u0438\u0431\u0443\u0434\u044c \u0437\u0430\u0445\u043e\u0447\u0435\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u044d\u043a\u0432\u0438\u0432\u0430\u043b\u0435\u043d\u0442\u043d\u044b\u0439 \u043a\u043e\u0434 (\u0434\u043b\u044f \u043f\u043e\u043b\u043d\u043e\u0442\u044b \u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0430) \u0431\u0443\u0434\u0443 \u0440\u0430\u0434 \u0432\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0441\u044e\u0434\u0430.     \t<\/p>\n<div class=\"clear\"><\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"http:\/\/habrahabr.ru\/post\/261201\/\"> http:\/\/habrahabr.ru\/post\/261201\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>     \t\u0414\u043e\u0431\u0440\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441\u0443\u0442\u043e\u043a, \u0445\u0430\u0431\u0440!<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/d80\/6c9\/61a\/d806c961a07d4ebfaeda1dbf56a621fa.png\" align=\"left\"\/><br \/>  \u041c\u043e\u0438\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u043c \u042f\u041f \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f D. \u0412\u0441\u0435\u0433\u0434\u0430 \u043f\u043e\u043d\u0438\u043c\u0430\u043b, \u0447\u0442\u043e \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0438\u0433\u0440\u044b\u0432\u0430\u0442\u044c C++ \u0438\u0437-\u0437\u0430 \u0441\u0431\u043e\u0440\u0449\u0438\u043a\u0430, \u043a\u0430\u043a\u0438\u0445-\u0442\u043e \u0432\u044b\u0441\u043e\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u0445 \u043f\u043b\u044e\u0448\u0435\u043a \u0438 \u0442.\u0434. \u041d\u043e \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0434\u043e\u0445\u043e\u0434\u0438\u043b\u0438 \u0440\u0443\u043a\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e. \u0420\u0435\u0448\u0438\u043b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u0435\u043d\u044c\u043a\u0438\u0439 \u043a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 (\u0434\u0430\u0436\u0435 \u043d\u0435 \u043f\u043e\u043c\u043d\u044e \u043c\u0435\u0442\u043e\u0434 \u043a\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f) \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c. \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043c\u0435\u043d\u044f \u043f\u0440\u0438\u044f\u0442\u043d\u043e \u0443\u0434\u0438\u0432\u0438\u043b: \u0432\u0435\u0440\u0441\u0438\u044f C++ \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0430 \u0437\u0430 5.47 \u0441\u0435\u043a, \u0432\u0435\u0440\u0441\u0438\u044f D \u2014 \u0437\u0430 5.55 \u0441\u0435\u043a. \u00ab0.08 \u0441\u0435\u043a \u043f\u0440\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0444\u0430\u0439\u043b\u0430 \u0432 74\u041c\u0431 \u044d\u0442\u043e \u043d\u0435 \u0442\u0430\u043a \u0443\u0436 \u0438 \u043c\u043d\u043e\u0433\u043e\u00bb \u2014 \u043f\u043e\u0434\u0443\u043c\u0430\u043b \u044f. \u041d\u043e, \u043d\u0430 \u0432\u0441\u044f\u043a\u0438\u0439 \u0441\u043b\u0443\u0447\u0430\u0439, \u0440\u0435\u0448\u0438\u043b \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u043a\u043e\u0434 \u043d\u0430 D \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e gdc (dmd \u043a\u0430\u043a frontend, gnu backend) \u0438 \u0442\u0443\u0442 \u0443\u0436\u0435 \u0432 \u0434\u0443\u0448\u0443 \u0437\u0430\u043a\u0440\u0430\u043b\u0438\u0441\u044c \u0441\u043e\u043c\u043d\u0435\u043d\u0438\u044f, \u0447\u0442\u043e \u044f \u0432\u0441\u0451 \u0441\u0434\u0435\u043b\u0430\u043b \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e: \u043a\u043e\u0434 \u043e\u0442\u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0437\u0430 4.01 \u0441\u0435\u043a, \u0447\u0442\u043e \u0431\u043e\u043b\u0435\u0435 \u0447\u0435\u043c \u043d\u0430 20% \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0432\u0435\u0440\u0441\u0438\u0438 \u043d\u0430 \u0421++. \u0420\u0435\u0448\u0438\u043b \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e ldc2 (dmd frontend, llvm backend): 2.92(!!) \u0441\u0435\u043a. \u0422\u0443\u0442 \u044f \u0440\u0435\u0448\u0438\u043b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f.  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-260179","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/260179","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=260179"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/260179\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=260179"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=260179"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=260179"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}