{"id":297121,"date":"2020-01-14T15:00:12","date_gmt":"2020-01-14T15:00:12","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=297121"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=297121","title":{"rendered":"\u0411\u044b\u0441\u0442\u0440\u0435\u0435, \u0447\u0435\u043c C++; \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435, \u0447\u0435\u043c PHP"},"content":{"rendered":"\n<div class=\"post__text post__text-html\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/483864\/\">\n<p>\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440.<\/p>\n<p>  <\/p>\n<p>\u0423 \u043c\u0435\u043d\u044f \u0442\u0443\u0442 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e \u043a\u043e\u0434 \u043d\u0430 \u0445\u0430\u0441\u043a\u0435\u043b\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0441\u044f \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u043d\u0430 C++. \u0418\u043d\u043e\u0433\u0434\u0430 \u2014 \u043d\u0430 40%.<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/83\/fd\/a4\/83fda4sz5x37klkngozxiczziwg.png\"><br \/>  <em>(\u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b, \u043c\u0435\u043d\u044c\u0448\u0435 \u2014 \u043b\u0443\u0447\u0448\u0435, C++ \u0441\u043d\u0438\u0437\u0443)<\/em><\/p>\n<p>  <\/p>\n<p>\u0427\u0442\u043e \u0441\u0430\u043c\u043e\u0435 \u0441\u043c\u0435\u0448\u043d\u043e\u0435 \u2014 \u044f \u0441\u043e\u0431\u0438\u0440\u0430\u043b \u0445\u0430\u0441\u043a\u0435\u043b\u044c-\u043a\u043e\u0434 \u0447\u0435\u0440\u0435\u0437 LLVM-\u0431\u0435\u043a\u0435\u043d\u0434, \u043d\u043e \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u043b \u0441 GCC. \u0415\u0441\u043b\u0438 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c \u0441 clang (\u0447\u0442\u043e \u0432\u0440\u043e\u0434\u0435 \u043a\u0430\u043a \u043b\u043e\u0433\u0438\u0447\u043d\u0435\u0435), \u0442\u043e \u0432\u0441\u0451 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0435\u0449\u0451 \u0445\u0443\u0436\u0435 \u0434\u043b\u044f \u043f\u043b\u044e\u0441\u043e\u0432: \u043f\u043e\u0447\u0435\u043c\u0443-\u0442\u043e \u043d\u0430 \u044d\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435 clang \u043f\u0440\u043e\u0438\u0433\u0440\u044b\u0432\u0430\u0435\u0442 GCC \u0432 \u043f\u0430\u0440\u0443 \u0440\u0430\u0437, \u0438 \u0440\u0430\u0437\u043d\u0438\u0446\u0430 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043d\u0435 40%, \u0430 \u044d\u0442\u0430\u043a \u0440\u0430\u0437\u0430 \u0442\u0440\u0438. \u0412\u043f\u0440\u043e\u0447\u0435\u043c, \u043e\u0434\u043d\u0430 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0430\u044f \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f C++-\u043a\u043e\u0434\u0430 \u044d\u0442\u043e \u043f\u043e\u043c\u0435\u043d\u044f\u0435\u0442.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u0447\u0430\u043b\u043e\u0441\u044c \u0432\u0441\u0451 \u0441 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u043c\u043e\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 (\u043a\u043e\u0442\u043e\u0440\u044b\u0439, \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0445\u0430\u0441\u043a\u0435\u043b\u0435, \u0438 \u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u044f \u0442\u043e\u0436\u0435 \u0441\u043a\u043e\u0440\u043e \u043d\u0430\u043f\u0438\u0448\u0443) \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b\u0441\u0442\u0440\u043e \u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u041b\u0435\u0432\u0435\u043d\u0448\u0442\u0435\u0439\u043d\u0430 \u043c\u0435\u0436\u0434\u0443 \u0434\u0432\u0443\u043c\u044f \u0441\u0442\u0440\u043e\u043a\u0430\u043c\u0438. \u0420\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u041b\u0435\u0432\u0435\u043d\u0448\u0442\u0435\u0439\u043d\u0430 \u2014 \u044d\u0442\u043e \u0442\u0430\u043a\u0430\u044f \u043c\u0435\u0442\u0440\u0438\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0433\u043e\u0432\u043e\u0440\u0438\u0442, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u043d\u0443\u0436\u043d\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c, \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0438\u043b\u0438 \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0432 \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435, \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0430 \u0441\u0442\u0430\u043b\u0430 \u0440\u0430\u0432\u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435. \u042f \u0441\u0447\u0438\u0442\u0430\u043b \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0438\u043c\u0438 \u0441\u0442\u0440\u043e\u043a\u0430\u043c\u0438 (\u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0430 \u0434\u0435\u0441\u044f\u0442\u043a\u043e\u0432 \u0442\u044b\u0441\u044f\u0447 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432), \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c \u0431\u044b\u043b\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u0430\u0436\u043d\u0430.<\/p>\n<p>  <\/p>\n<p>\u0410 \u043f\u043e\u0442\u043e\u043c \u043c\u043d\u0435 \u0441\u0442\u0430\u043b\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0431\u044b\u0441\u0442\u0440\u043e \u044f \u0432\u043e\u043e\u0431\u0449\u0435 \u043c\u043e\u0433\u0443 \u044d\u0442\u043e \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0441\u0447\u0438\u0442\u0430\u0442\u044c (\u043f\u043e\u0442\u0440\u0430\u0442\u0438\u0432 \u0440\u0430\u0437\u0443\u043c\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0430 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044e, \u043a\u043e\u043d\u0435\u0447\u043d\u043e), \u0442\u0430\u043a \u0447\u0442\u043e \u044f \u043d\u0430\u0431\u0440\u043e\u0441\u0430\u043b \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u043d\u0430 \u0421++ \u0438 \u0432\u0437\u044f\u043b \u0435\u0433\u043e \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0437\u0430 \u044d\u0442\u0430\u043a\u0438\u0439 \u0438\u0434\u0435\u0430\u043b, \u043a \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u0441\u0442\u043e\u0438\u0442 \u0441\u0442\u0440\u0435\u043c\u0438\u0442\u044c\u0441\u044f. \u0412\u043f\u0440\u043e\u0447\u0435\u043c, \u043a\u0430\u043a \u0443\u0436\u0435 \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u0438\u0434\u0435\u0430\u043b \u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f \u043f\u0440\u0435\u0432\u0437\u043e\u0439\u0434\u0451\u043d.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0441\u0442\u0438\u0447\u044c?<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/b51\/03d\/1b9\/b5103d1b96fa82c7316d26bab06678f8.jpg\"><\/p>\n<p>  <\/p>\n<p>\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0431\u043e\u043d\u0443\u0441\u0430 \u2014 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0441 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u044f\u0437\u044b\u043a\u0430\u043c\u0438. \u0421\u043f\u043e\u0439\u043b\u0435\u0440\u044b:<\/p>\n<p>  <\/p>\n<ul>\n<li>Nim \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 C \u0434\u0432\u0430\u0434\u0446\u0430\u0442\u0438\u043b\u0435\u0442\u043d\u0435\u0439 \u0434\u0430\u0432\u043d\u043e\u0441\u0442\u0438.<\/li>\n<li>C# \u0432 \u043f\u044f\u0442\u044c \u0440\u0430\u0437 \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435 Java, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u043f\u043e\u043b\u043d\u0435 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 Rust.<\/li>\n<li>Go \u0432\u0440\u043e\u0432\u0435\u043d\u044c \u0441 C.<\/li>\n<li>PHP \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u043f\u0438\u0442\u043e\u043d\u0430 (\u0447\u0442\u043e \u043e\u043f\u0440\u0430\u0432\u0434\u044b\u0432\u0430\u0435\u0442 \u0432\u0442\u043e\u0440\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430).<\/li>\n<\/ul>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041f\u0440\u043e \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u041b\u0435\u0432\u0435\u043d\u0448\u0442\u0435\u0439\u043d\u0430<\/b><\/p>\n<div class=\"spoiler_text\">\n<p>\u041d\u0430\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u0435 \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u041b\u0435\u0432\u0435\u043d\u0448\u0442\u0435\u0439\u043d\u0430 \u2014 \u043a\u0430\u043a \u0440\u0430\u0437 \u043e\u0434\u043d\u0430 \u0438\u0437 \u0442\u0435\u0445 \u0437\u0430\u0434\u0430\u0447, \u0447\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0430 \u0434\u043b\u044f \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%A0%D0%B0%D1%81%D1%81%D1%82%D0%BE%D1%8F%D0%BD%D0%B8%D0%B5_%D0%9B%D0%B5%D0%B2%D0%B5%D0%BD%D1%88%D1%82%D0%B5%D0%B9%D0%BD%D0%B0\" rel=\"nofollow\">\u041a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435<\/a> \u0441\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043a \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044e \u043c\u0430\u0442\u0440\u0438\u0446\u044b \u0440\u0430\u0437\u043c\u0435\u0440\u0430 <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/e9f\/bbe\/c2a\/e9fbbec2ad9c447d5cc57054439b7979.svg\" alt=\"$m \\times n$\" data-tex=\"inline\"><\/math> (\u0433\u0434\u0435 <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/e2e\/33f\/15a\/e2e33f15a96008ca33579599483c4531.svg\" alt=\"$m$\" data-tex=\"inline\"><\/math> \u0438 <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/08d\/9fa\/efb\/08d9faefbe272bdf8fbb80773542e343.svg\" alt=\"$n$\" data-tex=\"inline\"><\/math> \u2014 \u0434\u043b\u0438\u043d\u044b \u0441\u0442\u0440\u043e\u043a) \u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0447\u043d\u043e\u043c\u0443 \u0435\u0451 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044e \u0441\u0432\u0435\u0440\u0445\u0443 \u0432\u043d\u0438\u0437. \u0423\u0432\u044b, \u0435\u0441\u043b\u0438 \u0441\u0442\u0440\u043e\u043a\u0438 \u0438\u043c\u0435\u044e\u0442 \u0441\u043c\u0435\u0448\u043d\u043e\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u043f\u043e\u0440\u044f\u0434\u043a\u0430 \u0434\u0435\u0441\u044f\u0442\u043a\u0430 \u043a\u0438\u043b\u043e\u0431\u0430\u0439\u0442, \u0442\u043e \u0442\u0430\u043a\u0430\u044f \u043c\u0430\u0442\u0440\u0438\u0446\u0430 \u0441\u043e\u0436\u0440\u0451\u0442 0.5-1 \u0433\u0438\u0433\u0430\u0431\u0430\u0439\u0442, \u0447\u0442\u043e \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u0438\u044f\u0442\u043d\u043e. \u041e\u0434\u043d\u0430\u043a\u043e, \u0435\u0441\u043b\u0438 \u043f\u0440\u0438\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c\u0441\u044f, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u043c\u044b \u0432 \u043a\u0430\u0436\u0434\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u0432\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 (\u0442\u0435\u043a\u0443\u0449\u0443\u044e \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u0443\u044e \u0438 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0443\u044e), \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u043e\u0436\u043d\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0445.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u043e\u0439\u0442\u0438\u0441\u044c \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u043e\u0439, \u043d\u043e \u043d\u0430\u043c \u0438 \u0441 \u0434\u0432\u0443\u043c\u044f \u0445\u043e\u0440\u043e\u0448\u043e \u0431\u0443\u0434\u0435\u0442.<\/p>\n<\/div>\n<\/div>\n<p>  <\/p>\n<h1 id=\"benchmarking\">\u0411\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0438\u043d\u0433<\/h1>\n<p>  <\/p>\n<p>\u0411\u0443\u0434\u0435\u043c \u0437\u0430\u043c\u0435\u0440\u044f\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0434\u0432\u0443\u043c\u044f \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c\u0438.<\/p>\n<p>  <\/p>\n<p>\u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u0435\u0441\u0442\u044c \u0437\u0430\u043c\u0435\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u043a\u0435\u0442 <a href=\"https:\/\/hackage.haskell.org\/package\/criterion\" rel=\"nofollow\">criterion<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0434\u0435\u043b\u0430\u0442\u044c \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0438 <em>\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e<\/em>, \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u044f \u043a\u043e\u0434 \u043c\u043d\u043e\u0433\u043e \u0440\u0430\u0437, \u0432\u044b\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u044f \u0432\u0441\u044f\u043a\u0438\u0435 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0435 \u043e\u0442\u043a\u043b\u043e\u043d\u0435\u043d\u0438\u044f \u0438 \u043f\u0440\u043e\u0447\u0438\u0435 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438.<\/p>\n<p>  <\/p>\n<p>\u041d\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0435\u0433\u043e \u0434\u043e\u043b\u0433\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0443 \u043d\u0430\u0441 \u0431\u0443\u0434\u0435\u0442 \u0435\u0449\u0451 \u043e\u0434\u0438\u043d \u043d\u0430\u043a\u043e\u043b\u0435\u043d\u043d\u044b\u0439 \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a. \u0412\u043e\u0437\u044c\u043c\u0451\u043c \u0442\u0440\u0438 \u0441\u0442\u0440\u043e\u043a\u0438 <code>s1<\/code>, <code>s2<\/code>, <code>s3<\/code>, \u043f\u0435\u0440\u0432\u044b\u0435 \u0434\u0432\u0435 \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u043e\u0441\u0442\u043e\u044f\u0442 \u0438\u0437 20000 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 <code>'a'<\/code>, \u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u2014 \u0438\u0437 20000 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 <code>'b'<\/code>, \u0438 \u0431\u0443\u0434\u0435\u043c \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043e\u0442 <code>s1<\/code> \u0434\u043e <code>s2<\/code> \u0438 \u043e\u0442 <code>s1<\/code> \u0434\u043e <code>s3<\/code> (\u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u043e\u0436\u0438\u0434\u0430\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c 0 \u0438 20000).<\/p>\n<p>  <\/p>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u0441\u043e\u0442\u043d\u0438 \u043a\u0438\u043b\u043e\u0431\u0430\u0439\u0442 \u0438 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0438\u0445 \u043e\u0434\u043d\u0438\u043c \u0438 \u0442\u0435\u043c \u0436\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u043c \u2014 \u043d\u0438\u0447\u0442\u043e \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u044b \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430, \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0431\u0443\u0434\u0435\u043c \u0437\u0430\u043c\u0435\u0440\u044f\u0442\u044c \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0432\u0441\u0435\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b (\u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0445\u0430\u0441\u043a\u0435\u043b\u044f \u2014 \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e <code>+RTS -sstderr<\/code>). \u0427\u0442\u043e\u0431\u044b \u043d\u0435 \u0434\u0435\u043b\u0430\u0442\u044c \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a \u0441\u043e\u0432\u0441\u0435\u043c \u0443\u0436 \u043d\u0430\u043a\u043e\u043b\u0435\u043d\u043d\u044b\u043c, \u0437\u0430\u0449\u0438\u0442\u0438\u043c\u0441\u044f \u043e\u0442 \u0432\u044b\u0431\u0440\u043e\u0441\u043e\u0432: \u0431\u0443\u0434\u0435\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043a\u043e\u0434 \u0442\u0440\u0438 \u0440\u0430\u0437\u0430 \u0438 \u0431\u0440\u0430\u0442\u044c \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u0438\u0437 \u0442\u0440\u0451\u0445. \u041c\u0438\u043d\u0438\u043c\u0443\u043c, \u0430 \u043d\u0435 \u0441\u0440\u0435\u0434\u043d\u0435\u0435 \u2014 \u0442\u0430\u043a \u043a\u0430\u043a \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u0430\u044f \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c \u043d\u0430 \u043c\u0430\u0448\u0438\u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043a\u043e\u0434 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c\u0441\u044f \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435, \u0447\u0435\u043c \u043e\u043d \u0435\u0441\u0442\u044c \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435, \u0430 \u0432\u043e\u0442 \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f. \u0422\u0435\u043c \u0431\u043e\u043b\u0435\u0435, \u0447\u0442\u043e \u043d\u0438\u043a\u0430\u043a\u043e\u0439 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e\u0441\u0442\u0438 \u0432\u043e \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0443 \u043d\u0430\u0441 \u043d\u0435\u0442, \u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0441\u0442\u0440\u043e\u0433\u043e \u0434\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e \u0445\u043e\u0434\u0443 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u043a\u043e\u0434\u0430 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u043b\u0438\u0448\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u043a\u043e\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0430, \u0430 \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u044b\u0435 \u0433\u0440\u0430\u0444\u0438\u043a\u0438 criterion&#8217;\u0430 \u0431\u0443\u0434\u0443\u0442 \u0432 \u0441\u0430\u043c\u043e\u043c \u043a\u043e\u043d\u0446\u0435.<\/p>\n<p>  <\/p>\n<h1 id=\"k-chemu-stremitsya\">\u041a \u0447\u0435\u043c\u0443 \u0441\u0442\u0440\u0435\u043c\u0438\u0442\u044c\u0441\u044f?<\/h1>\n<p>  <\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u0447\u043d\u0451\u043c \u0441 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0439: \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0431\u044b\u0441\u0442\u0440\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0440\u0435\u0448\u0438\u0442\u044c \u043d\u0430\u0448\u0443 \u0437\u0430\u0434\u0430\u0447\u0443 \u0432 \u044d\u0442\u0438\u0445 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0445? \u042d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043e\u0446\u0435\u043d\u0438\u0442\u044c \u0434\u0432\u0443\u043c\u044f \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c\u0438: \u043e\u0447\u0435\u043d\u044c \u0433\u0440\u0443\u0431\u043e \u0442\u0435\u043e\u0440\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0438 \u0447\u0443\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u043e \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438.<\/p>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0422\u0435\u043e\u0440\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438<\/b><\/p>\n<div class=\"spoiler_text\">\n<p>\u041f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u043c, \u0447\u0442\u043e \u0432\u0441\u0435 \u043d\u0430\u0448\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043c\u0435\u0449\u0430\u044e\u0442\u0441\u044f \u0432 L2-\u043a\u0435\u0448, \u043d\u043e \u0438\u0437 L1 \u043e\u043d\u0438 \u0442\u0430\u043a\u0438 \u0432\u044b\u043c\u044b\u0432\u0430\u044e\u0442\u0441\u044f. \u041e\u0431\u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043e \u043b\u0438 \u044d\u0442\u043e \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u0435? \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u044c:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0414\u0432\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 \u043f\u043e 20000 \u0431\u0430\u0439\u0442: \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e 40 \u043a\u0438\u043b\u043e\u0431\u0430\u0439\u0442 (\u044d\u0442\u043e \u0443\u0436\u0435 \u0431\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c L1 \u043d\u0430 \u043c\u043e\u0435\u0439 \u043c\u0430\u0448\u0438\u043d\u0435!).<\/li>\n<li>\u0414\u0432\u0430 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u043f\u043e 20000 8-\u0431\u0430\u0439\u0442\u043d\u044b\u0445 \u0447\u0438\u0441\u0435\u043b, \u0447\u0442\u043e \u0434\u0430\u0451\u0442 \u043d\u0430\u043c \u0434\u0432\u0430\u0436\u0434\u044b \u043f\u043e 160 \u2014 \u0438\u0442\u043e\u0433\u043e 320 \u043a\u0438\u043b\u043e\u0431\u0430\u0439\u0442 (\u0438 \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u0431\u044b \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 4-\u0431\u0430\u0439\u0442\u043d\u044b\u0435 \u0438\u043d\u0442\u044b, \u0442\u043e \u044d\u0442\u043e \u0431\u044b \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u0431\u044b\u043b\u043e 160 \u043a\u0438\u043b\u043e\u0431\u0430\u0439\u0442, \u0447\u0442\u043e \u043a\u0443\u0434\u0430 \u0431\u043e\u043b\u044c\u0448\u0435 L1).<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0421\u043a\u043e\u043b\u044c\u043a\u043e \u0434\u0430\u043d\u043d\u044b\u0445 \u0437\u0430 \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0432\/\u0438\u0437 L2?<\/p>\n<p>  <\/p>\n<p>\u041c\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0432 \u0440\u0430\u0439\u043e\u043d\u0435 20000 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0439, \u043a\u0430\u0436\u0434\u0430\u044f \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0447\u0438\u0442\u0430\u0435\u0442 \u043e\u0434\u043d\u0443 \u0438\u0437 \u0441\u0442\u0440\u043e\u043a \u0446\u0435\u043b\u0438\u043a\u043e\u043c (20 \u041a\u0411), \u0432\u0435\u0441\u044c \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0439 \u043d\u0430 \u043f\u0440\u043e\u0448\u043b\u043e\u043c \u0448\u0430\u0433\u0435 \u043c\u0430\u0441\u0441\u0438\u0432 (160 \u041a\u0411), \u0438 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043f\u0438\u0448\u0435\u0442 \u043d\u043e\u0432\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 (\u0435\u0449\u0451 160 \u041a\u0411). \u041e\u043f\u0442\u0438\u043c\u0438\u0441\u0442\u0438\u0447\u043d\u043e \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u044f, \u0447\u0442\u043e \u0437\u0430\u043f\u0438\u0441\u044c \u043d\u0438 \u043d\u0430 \u0447\u0442\u043e \u043d\u0435 \u0432\u043b\u0438\u044f\u0435\u0442 (\u0443 \u043d\u0430\u0441 \u0436\u0435 \u0433\u0440\u0443\u0431\u0430\u044f \u043e\u0446\u0435\u043d\u043a\u0430 <em>\u0441\u043d\u0438\u0437\u0443<\/em>) \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u0435\u043d\u0438\u0435: \u0441\u0443\u043c\u043c\u0430\u0440\u043d\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c (20 + 160)\u00d720000 \u041a\u0411 \u0438\u0437 L2, \u0447\u0442\u043e \u0440\u0430\u0432\u043d\u043e 3.6 \u0413\u0411. \u0423\u0447\u0438\u0442\u044b\u0432\u0430\u044f, \u0447\u0442\u043e, \u0441\u0443\u0434\u044f \u043f\u043e \u0440\u0430\u0437\u043d\u044b\u043c \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430\u043c, \u043c\u043e\u0439 Haswell \u0438\u043c\u0435\u0435\u0442 \u0443\u0441\u0442\u043e\u044f\u0432\u0448\u0443\u044e\u0441\u044f \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u0447\u0442\u0435\u043d\u0438\u044f \u0438\u0437 L2 \u0432 \u0440\u0430\u0439\u043e\u043d\u0435 50 \u0413\u0411\/\u0441, \u044d\u0442\u043e \u0434\u0430\u0441\u0442 \u043d\u0430\u043c \u043f\u043e\u0440\u044f\u0434\u043a\u0430 0.1 \u0441 \u043d\u0430 \u043e\u0434\u043d\u0443 \u043f\u0430\u0440\u0443 \u0441\u0442\u0440\u043e\u043a, \u0438\u043b\u0438 0.2 \u0441 \u043d\u0430 \u0432\u0435\u0441\u044c \u0442\u0435\u0441\u0442. \u0411\u044b\u0441\u0442\u0440\u0435\u0435 \u043c\u044b \u043d\u0438\u043a\u0430\u043a \u043d\u0435 \u043c\u043e\u0436\u0435\u043c.<\/p>\n<p>  <\/p>\n<p>\u041d\u0443, \u0442\u043e \u0435\u0441\u0442\u044c, \u0441\u043e\u0432\u0441\u0435\u043c \u0442\u0435\u043e\u0440\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043c\u043e\u0433\u043b\u0438 \u0431\u044b, \u043d\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u0431\u043b\u043e\u0447\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043c\u0435\u0449\u0430\u0442\u044c\u0441\u044f \u0432 L1, \u0441\u043e\u0432\u0441\u0435\u043c \u043d\u0435 \u043f\u043e\u0434\u043d\u044f\u043b\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c.<\/p>\n<\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438<\/b><\/p>\n<div class=\"spoiler_text\">\n<p>\u041d\u0430\u0431\u0440\u043e\u0441\u0430\u0435\u043c \u0432\u043e\u0442 \u044d\u0442\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443 \u043d\u0430 C++:<\/p>\n<p>  <\/p>\n<pre><code class=\"cpp\">#include &lt;algorithm&gt; #include &lt;iostream&gt; #include &lt;numeric&gt; #include &lt;vector&gt; #include &lt;string&gt;  size_t lev_dist(const std::string&amp; s1, const std::string&amp; s2) {   const auto m = s1.size();   const auto n = s2.size();    std::vector&lt;int64_t&gt; v0;   v0.resize(n + 1);   std::iota(v0.begin(), v0.end(), 0);    auto v1 = v0;    for (size_t i = 0; i &lt; m; ++i)   {     v1[0] = i + 1;      for (size_t j = 0; j &lt; n; ++j)     {       auto delCost = v0[j + 1] + 1;       auto insCost = v1[j] + 1;       auto substCost = s1[i] == s2[j] ? v0[j] : (v0[j] + 1);        v1[j + 1] = std::min({ delCost, insCost, substCost });     }      std::swap(v0, v1);   }    return v0[n]; }  int main() {     std::string s1(20000, 'a');     std::string s2(20000, 'a');     std::string s3(20000, 'b');      std::cout &lt;&lt; lev_dist(s1, s2) &lt;&lt; std::endl;     std::cout &lt;&lt; lev_dist(s1, s3) &lt;&lt; std::endl; }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041c\u0438\u043d\u0438\u043c\u0443\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0438\u0437 \u0442\u0440\u0451\u0445 \u0437\u0430\u043f\u0443\u0441\u043a\u043e\u0432 \u2014 1.356 \u0441\u0435\u043a\u0443\u043d\u0434 (Core i7 4770, \u043d\u0438\u043a\u0430\u043a\u043e\u0433\u043e \u043e\u0432\u0435\u0440\u043a\u043b\u043e\u043a\u0438\u043d\u0433\u0430). \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0441\u044f gcc 9.2, \u043e\u043f\u0446\u0438\u0438 \u2014 <code>-O3 -march=native<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041a\u0430\u043a \u0443\u0436\u0435 \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043b\u043e\u0441\u044c \u0432\u043e \u0432\u0432\u0435\u0434\u0435\u043d\u0438\u0438, clang (9.0.1, \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0441 \u0442\u0435\u043c\u0438 \u0436\u0435 \u043e\u043f\u0446\u0438\u044f\u043c\u0438) \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0441\u0435\u0431\u044f \u0445\u0443\u0436\u0435: \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u0440\u0430\u0439\u043e\u043d\u0435 2.6-2.7 \u0441.<\/p>\n<\/div>\n<\/div>\n<p>  <\/p>\n<p>\u0422\u0430\u043a \u0447\u0442\u043e \u043d\u0430\u0448\u0430 \u0446\u0435\u043b\u044c \u2014 1.3 \u0441\u0435\u043a\u0443\u043d\u0434\u044b.<\/p>\n<p>  <\/p>\n<h1 id=\"kod\">\u041a\u043e\u0434<\/h1>\n<p>  <\/p>\n<h2 id=\"naivnaya-chistaya-realizaciya\">\u041d\u0430\u0438\u0432\u043d\u0430\u044f \u0447\u0438\u0441\u0442\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f<\/h2>\n<p>  <\/p>\n<p>\u041d\u0438\u043a\u0430\u043a\u043e\u0439 \u044f\u0432\u043d\u043e\u0439 \u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 (\u043a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0432\u043d\u0443\u0442\u0440\u0438 <code>Data.Vector<\/code>, \u043d\u043e \u044d\u0442\u043e \u043d\u0435 \u043d\u0430\u0448\u0430 \u043a\u0443\u0445\u043d\u044f), \u043d\u0438\u043a\u0430\u043a\u043e\u0439 \u044f\u0432\u043d\u043e\u0439 \u0445\u0432\u043e\u0441\u0442\u043e\u0432\u043e\u0439 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0438. \u041f\u0440\u043e\u0441\u0442\u043e \u0441\u0442\u0440\u043e\u0433\u0430\u044f \u043b\u0435\u0432\u0430\u044f \u0441\u0432\u0451\u0440\u0442\u043a\u0430 \u0438 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043a\u043e\u0441\u0442\u044b\u043b\u044c\u043d\u044b\u0439 <code>Data.Vector.constructN<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">import qualified Data.ByteString as BS import qualified Data.Vector.Unboxed as V import Data.List  levenshteinDistance :: BS.ByteString -&gt; BS.ByteString -&gt; Int levenshteinDistance s1 s2 = foldl' outer (V.generate (n + 1) id) [0 .. m - 1] V.! n   where     m = BS.length s1     n = BS.length s2      outer v0 i = V.constructN (n + 1) ctr       where         s1char = s1 `BS.index` i         ctr v1 | V.length v1 == 0 = i + 1         ctr v1 = min (substCost + substCostBase) $ 1 + min delCost insCost           where             j = V.length v1             delCost = v0 V.! j             insCost = v1 V.! (j - 1)             substCostBase = v0 V.! (j - 1)             substCost = if s1char == s2 `BS.index` (j - 1) then 0 else 1<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0443\u0440\u043e\u0434\u043b\u0438\u0432\u044b\u043c, \u043d\u043e, \u043d\u0430 \u043c\u043e\u0439 \u0432\u0437\u0433\u043b\u044f\u0434, \u044d\u0442\u043e \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0447\u0438\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u044b\u0439 \u0438 \u0438\u0434\u0438\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u044b\u0439 \u043a\u043e\u0434 (\u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u0430\u043a\u0438\u0435 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u044b \u0432\u043e\u043e\u0431\u0449\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0438\u0434\u0438\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c\u044b\u043c\u0438).<\/p>\n<p>  <\/p>\n<p>\u0412\u0440\u0435\u043c\u044f \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u043d\u0430\u043a\u043e\u043b\u0435\u043d\u043d\u043e\u043c\u0443 \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0443? <strong><em>5.5 \u0441\u0435\u043a\u0443\u043d\u0434<\/em><\/strong>. \u041a\u0430\u043a-\u0442\u043e \u043d\u0435 \u043e\u0447.<\/p>\n<p>  <\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u043b\u0438 \u043b\u0443\u0447\u0448\u0435?<\/p>\n<p>  <\/p>\n<h3 id=\"trivialnye-uluchsheniya\">\u0422\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u044b\u0435 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f<\/h3>\n<p>  <\/p>\n<p>\u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e, \u0435\u0441\u0442\u044c \u043f\u0430\u0440\u0430 \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u0443\u043b\u0443\u0447\u0448\u0438\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u0442\u0440\u043e\u0433\u0430\u044f \u043a\u043e\u0434.<\/p>\n<p>  <\/p>\n<p>\u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u0432\u0440\u044f\u0434 \u043b\u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u0432\u044b\u0432\u0435\u043b \u0432\u0441\u0435 \u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440\u0438\u0441\u0442\u0438\u043a\u0438 \u0441\u0442\u0440\u043e\u0433\u043e\u0441\u0442\u0438. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0435\u043c\u0443 \u043f\u043e\u043c\u043e\u0436\u0435\u043c \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043c <code>{-# LANGUAGE Strict #-}<\/code> \u0432 \u0441\u0430\u043c\u043e\u0435 \u043d\u0430\u0447\u0430\u043b\u043e \u0444\u0430\u0439\u043b\u0430. \u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u0431\u044b\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0434\u043e\u0442\u043e\u0448\u043d\u044b\u043c\u0438 \u0438 \u043d\u0430\u0447\u0430\u0442\u044c \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u043e \u0440\u0430\u0441\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c bang patterns, \u043d\u043e \u0438 \u0442\u0430\u043a \u0441\u043e\u0439\u0434\u0451\u0442.<\/p>\n<p>  <\/p>\n<p>\u0412 \u043b\u044e\u0431\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u044d\u0442\u043e \u0443\u043c\u0435\u043d\u044c\u0448\u0430\u0435\u0442 \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0434\u043e <strong><em>3.4 \u0441\u0435\u043a\u0443\u043d\u0434<\/em><\/strong>. \u041a\u0443\u0434\u0430 \u043b\u0443\u0447\u0448\u0435, \u043d\u043e \u0432\u0441\u0451 \u0435\u0449\u0451 \u0442\u0430\u043a \u0441\u0435\u0431\u0435.<\/p>\n<p>  <\/p>\n<p>\u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0432\u0434\u043e\u0431\u0430\u0432\u043e\u043a \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0435 \u0448\u0442\u0430\u0442\u043d\u044b\u0439 \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 GHC (NCG \u2014 Native CodeGen), \u0430 LLVM? \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u043c <code>{-# OPTIONS_GHC -fllvm #-}<\/code> \u0432 \u043d\u0430\u0447\u0430\u043b\u043e \u0444\u0430\u0439\u043b\u0430. \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442? <strong><em>2.1<\/em><\/strong> \u0441\u0435\u043a\u0443\u043d\u0434. \u042d\u0442\u043e \u0443\u0436\u0435 \u0447\u0442\u043e-\u0442\u043e! \u0418, \u043a\u0441\u0442\u0430\u0442\u0438, \u0443\u0436\u0435 \u0434\u0430\u0436\u0435 \u044d\u0442\u043e\u0442 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043b clang.<\/p>\n<p>  <\/p>\n<h2 id=\"chistaya-realizaciya-s-nebezopasnymi-operaciyami\">\u0427\u0438\u0441\u0442\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441 \u043d\u0435\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u043c\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f\u043c\u0438<\/h2>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0447\u0443\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0437\u043d\u0430\u0447\u0438\u043c\u044b\u0435 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f: \u0437\u0430\u043c\u0435\u043d\u0438\u043c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043f\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0443 \u0438\u0445 \u043d\u0435\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u043c\u0438 \u0432\u0435\u0440\u0441\u0438\u044f\u043c\u0438 (\u043a\u043e\u0442\u043e\u0440\u044b\u0435, \u0432\u043f\u0440\u043e\u0447\u0435\u043c, \u044d\u043a\u0432\u0438\u0432\u0430\u043b\u0435\u043d\u0442\u043d\u044b \u043f\u043e \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438 \u043f\u043b\u044e\u0441\u043e\u0432\u044b\u043c <code>operator[]<\/code>). \u0422\u0430\u043a <code>V.!<\/code> \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u0430 <code>V.unsafeIndex<\/code>, \u0430 <code>BS.index<\/code> \u043d\u0430 <code>BS.unsafeIndex<\/code>.<\/p>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"haskell\">import qualified Data.ByteString as BS import qualified Data.ByteString.Unsafe as BS import qualified Data.Vector.Unboxed as V import Data.List  levenshteinDistance :: BS.ByteString -&gt; BS.ByteString -&gt; Int levenshteinDistance s1 s2 = foldl' outer (V.generate (n + 1) id) [0 .. m - 1] V.! n   where     m = BS.length s1     n = BS.length s2      outer v0 i = V.constructN (n + 1) ctr       where         s1char = s1 `BS.unsafeIndex` i         ctr v1 | V.length v1 == 0 = i + 1         ctr v1 = min (substCost + substCostBase) $ 1 + min delCost insCost           where             j = V.length v1             delCost = v0 `V.unsafeIndex` j             insCost = v1 `V.unsafeIndex` (j - 1)             substCostBase = v0 `V.unsafeIndex` (j - 1)             substCost = if s1char == s2 `BS.unsafeIndex` (j - 1) then 0 else 1<\/code><\/pre>\n<\/div>\n<\/div>\n<p>  <\/p>\n<p>\u0418\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u0447\u0442\u043e \u0432 \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u043c\u0438\u0440\u0435 \u0445\u0430\u0441\u043a\u0435\u043b\u044f \u0441 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u043c\u0438 \u0442\u0438\u043f\u0430\u043c\u0438 \u043d\u0430\u043c \u0431\u044b \u043d\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u0443 \u0437\u0430\u043c\u0435\u043d\u0443: \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0434\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c \u0432\u0441\u0435\u0445 \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u0432, \u0442\u0435\u043c \u0441\u0430\u043c\u044b\u043c \u0438\u0437\u0431\u0430\u0432\u0438\u0432\u0448\u0438\u0441\u044c \u043e\u0442 \u0440\u0430\u043d\u0442\u0430\u0439\u043c-\u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u0438 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0432 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c.<\/p>\n<p>  <\/p>\n<p>\u0412 \u043b\u044e\u0431\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f (\u0431\u0435\u0437 \u0432\u0441\u0435\u0445 \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u0439) \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 <strong><em>4.2 \u0441\u0435\u043a\u0443\u043d\u0434\u044b<\/em><\/strong> (\u043f\u0440\u043e\u0442\u0438\u0432 5.5 \u0441\u0435\u043a\u0443\u043d\u0434 \u00ab\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0439\u00bb \u0432\u0435\u0440\u0441\u0438\u0438).<\/p>\n<p>  <\/p>\n<p>\u0410 \u0447\u0442\u043e \u0441 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f\u043c\u0438?<\/p>\n<p>  <\/p>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 <code>{-# LANGUAGE Strict #-}<\/code> \u0441\u043e\u043a\u0440\u0430\u0449\u0430\u0435\u0442 \u0432\u0440\u0435\u043c\u044f \u0434\u043e <strong><em>2.5 \u0441\u0435\u043a\u0443\u043d\u0434<\/em><\/strong> (\u043f\u0440\u043e\u0442\u0438\u0432 3.4 \u0441\u0435\u043a\u0443\u043d\u0434 \u00ab\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0439\u00bb \u0432\u0435\u0440\u0441\u0438\u0438).<\/p>\n<p>  <\/p>\n<p>\u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044f \u0447\u0435\u0440\u0435\u0437 LLVM \u0443\u043b\u0443\u0447\u0448\u0430\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0430\u0436 \u0434\u043e <strong><em>1.6 \u0441\u0435\u043a\u0443\u043d\u0434<\/em><\/strong> (\u043f\u0440\u043e\u0442\u0438\u0432 2.1 \u0441\u0435\u043a\u0443\u043d\u0434 \u0440\u0430\u043d\u0435\u0435). \u042d\u0442\u043e \u0443\u0436\u0435 \u0431\u044b\u0441\u0442\u0440\u0435\u0435 clang!<\/p>\n<p>  <\/p>\n<p>\u0418 \u0432\u043e\u043e\u0431\u0449\u0435, \u044d\u0442\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u043e \u0440\u044f\u0434\u0443 \u043f\u0440\u0438\u0447\u0438\u043d:<\/p>\n<p>  <\/p>\n<ol>\n<li>\u041c\u044b \u0443\u0436\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u043f\u043e\u0447\u0442\u0438-C++-\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u0432 \u0442\u043e \u0436\u0435 \u0432\u0440\u0435\u043c\u044f \u043f\u043e-\u043f\u0440\u0435\u0436\u043d\u0435\u043c\u0443 \u0438\u043c\u0435\u044f \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0438\u0434\u0438\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u044b\u0439 \u043a\u043e\u0434.<\/li>\n<li>\u041c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u0430\u043a\u0438\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u043c\u044b \u0430\u043b\u043b\u043e\u0446\u0438\u0440\u0443\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438 (\u0442\u043e \u0435\u0441\u0442\u044c, \u0432 20000 \u0440\u0430\u0437 \u0431\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 C++-\u0432\u0435\u0440\u0441\u0438\u044f). \u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e, \u043a\u0430\u0436\u0434\u044b\u0439 \u0442\u0430\u043a\u043e\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0434\u043e\u043b\u0433\u043e\u0436\u0438\u0432\u0443\u0449\u0438\u0439, \u0442\u0430\u043a \u0447\u0442\u043e \u043e\u043d \u0443\u043c\u0438\u0440\u0430\u0435\u0442 \u0438 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f GC \u0435\u0449\u0451 \u0432 <del>\u0440\u043e\u0434\u0434\u043e\u043c\u0435<\/del> \u043d\u0443\u043b\u0435\u0432\u043e\u043c \u043f\u043e\u043a\u043e\u043b\u0435\u043d\u0438\u0438. \u0421\u0431\u043e\u0440\u0449\u0438\u043a\u0438 \u043c\u0443\u0441\u043e\u0440\u0430 \u0441 \u043f\u043e\u043a\u043e\u043b\u0435\u043d\u0438\u044f\u043c\u0438 \u0440\u0443\u043b\u044f\u0442 \u0438 \u043f\u0435\u0434\u0430\u043b\u044f\u0442!<\/li>\n<li>\u00ab\u0428\u0442\u0440\u0430\u0444 \u0437\u0430 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c\u00bb \u0447\u0442\u043e \u0441\u0442\u0440\u043e\u0433\u043e\u0439, \u0447\u0442\u043e \u043d\u0435\u0441\u0442\u0440\u043e\u0433\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e 20% \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 NCG. \u041b\u0438\u0447\u043d\u043e \u044f \u0431\u044b \u043e\u0436\u0438\u0434\u0430\u043b \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043c\u0435\u043d\u044c\u0448\u0435\u0435 \u0432\u043b\u0438\u044f\u043d\u0438\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u043d\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u2014 \u043e\u043d\u0438 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0442, \u0442\u0430\u043a \u0447\u0442\u043e \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u0432\u0435\u0442\u0432\u043b\u0435\u043d\u0438\u0439 \u0434\u043e\u043b\u0436\u0435\u043d \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u043e \u043f\u043e\u043d\u044f\u0442\u044c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043f\u0430\u0442\u0442\u0435\u0440\u043d.<\/li>\n<li>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 LLVM-\u0431\u0435\u043a\u0435\u043d\u0434\u0430 \u0443\u043c\u0435\u043d\u044c\u0448\u0430\u0435\u0442 \u044d\u0442\u043e\u0442 \u0448\u0442\u0440\u0430\u0444 \u0434\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e 0.5 \u0441\u0435\u043a\u0443\u043d\u0434. \u041f\u043e\u0447\u0435\u043c\u0443? LLVM \u0441\u043f\u043e\u0441\u043e\u0431\u0435\u043d \u0438\u0437\u0431\u0430\u0432\u0438\u0442\u044c\u0441\u044f \u043e\u0442 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a, \u0438\u043b\u0438 \u0436\u0435 \u0441\u0430\u043c\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0442\u0441\u044f \u0431\u043e\u043b\u0435\u0435 \u0434\u0440\u0443\u0436\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c\u0438 \u043a \u043f\u0440\u0435\u0434\u0441\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044e \u0432\u0435\u0442\u0432\u043b\u0435\u043d\u0438\u0439? \u0418\u043b\u0438 \u043e\u0431\u0430 \u0444\u0430\u043a\u0442\u043e\u0440\u0430 \u0441\u0440\u0430\u0437\u0443?<\/li>\n<\/ol>\n<p>  <\/p>\n<h2 id=\"realizaciya-s-mutabelnostyu\">\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441 \u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e<\/h2>\n<p>  <\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u0447\u043d\u0451\u043c \u0441 \u043f\u0440\u044f\u043c\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u044b\u0432\u0430\u043d\u0438\u044f \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u043e\u0433\u043e <code>Data.Array.ST<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">import qualified Data.Array.Base as A(unsafeRead, unsafeWrite) import qualified Data.Array.ST as A import qualified Data.ByteString.Char8 as BS import Control.Monad import Control.Monad.ST  levenshteinDistance :: BS.ByteString -&gt; BS.ByteString -&gt; Int levenshteinDistance s1 s2 = runST $ do   v0Init &lt;- A.newListArray (0, n) [0..]   v1Init &lt;- A.newArray_ (0, n)   forM_ [0 .. m - 1] $ \\i -&gt; do     let (v0, v1) | even i = (v0Init, v1Init)                  | otherwise = (v1Init, v0Init)     loop i v0 v1   A.unsafeRead (if even m then v0Init else v1Init) n    where     m = BS.length s1     n = BS.length s2      loop :: Int -&gt; A.STUArray s Int Int -&gt; A.STUArray s Int Int -&gt; ST s ()     loop i v0 v1 = do       A.unsafeWrite v1 0 (i + 1)       let s1char = s1 `BS.index` i       forM_ [0..n - 1] $ \\j -&gt; do         delCost &lt;- v0 `A.unsafeRead` (j + 1)         insCost &lt;- v1 `A.unsafeRead` j         substCostBase &lt;- v0 `A.unsafeRead` j         let substCost = if s1char == s2 `BS.index` j then 0 else 1         A.unsafeWrite v1 (j + 1) $ min (substCost + substCostBase) $ 1 + min delCost insCost<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e \u043c\u043e\u0435\u043c\u0443 \u043e\u043f\u044b\u0442\u0443 \u043c\u0430\u0441\u0441\u0438\u0432\u044b (\u0432 \u0441\u043c\u044b\u0441\u043b\u0435 <code>Data.Array.ST<\/code>) \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0432\u0435\u043a\u0442\u043e\u0440\u043e\u0432 (<code>Data.Vector.Mutable<\/code> \u0438 \u0438\u0445 unboxed-\u0432\u0435\u0440\u0441\u0438\u044f) \u043f\u0440\u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u0434\u0435\u0441\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u044e\u0442\u0441\u044f. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 (\u0430 \u0442\u0430\u043a\u0436\u0435 \u0432 \u0446\u0435\u043b\u044f\u0445 \u0443\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044f \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u043f\u043e\u0441\u0442\u0430 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u0440\u0430\u0437\u0443\u043c\u043d\u043e\u0433\u043e) \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u0432\u0435\u0440\u0441\u0438\u044e \u043d\u0430 \u0432\u0435\u043a\u0442\u043e\u0440\u0430\u0445 \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c. \u0420\u043e\u0432\u043d\u043e \u043f\u043e \u0442\u0435\u043c \u0436\u0435 \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u00ab\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u044b\u0435\u00bb \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u0446\u0438\u0438 \u0438 \u0441\u0440\u0430\u0437\u0443 \u043e\u0431\u0440\u0430\u0442\u0438\u043c\u0441\u044f \u043a <code>unsafeRead<\/code>\/<code>unsafeWrite<\/code>. <\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0431\u044b\u0441\u0442\u0440\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u044d\u0442\u043e\u0442 \u0432\u0430\u0440\u0438\u0430\u043d\u0442?<\/p>\n<p>  <\/p>\n<p><strong><em>5.9 \u0441\u0435\u043a\u0443\u043d\u0434<\/em><\/strong>. \u0427\u0451\u0440\u0442. \u041a\u0443\u0434\u0430 \u0445\u0443\u0436\u0435, \u0447\u0435\u043c \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u0430\u044f \u0438 \u0447\u0438\u0441\u0442\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f! \u0418 \u0434\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043c\u044b \u043e\u0442\u043f\u0440\u043e\u0444\u0438\u043b\u0438\u0440\u0443\u0435\u043c \u044d\u0442\u043e\u0442 \u043a\u043e\u0434, \u0442\u043e \u043e\u043a\u0430\u0436\u0435\u0442\u0441\u044f, \u0447\u0442\u043e\u2026 \u0412 \u043e\u0431\u0449\u0435\u043c, \u043d\u0438\u0447\u0435\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0433\u043e \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u043d\u0435 \u0432\u044b\u0439\u0434\u0435\u0442.<\/p>\n<p>  <\/p>\n<p>\u0421 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u044d\u0442\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u043e \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043c\u0435\u0440\u0435 \u043f\u043e\u0447\u0442\u0438 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 GC: 2-3 \u043c\u0438\u043d\u043e\u0440\u043d\u044b\u0445 \u0441\u0431\u043e\u0440\u043a\u0438 \u043c\u0443\u0441\u043e\u0440\u0430 \u0438 2-3 \u043c\u0430\u0436\u043e\u0440\u043d\u044b\u0445 (\u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e <code>+RTS -sstderr<\/code>) \u043f\u0440\u043e\u0442\u0438\u0432 \u0442\u044b\u0441\u044f\u0447 \u043c\u0438\u043d\u043e\u0440\u043d\u044b\u0445 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0447\u0438\u0441\u0442\u043e\u0433\u043e <code>Data.Vector<\/code>. \u0412\u043f\u0440\u043e\u0447\u0435\u043c, \u043a\u0430\u043a \u043c\u044b \u0432\u0438\u0434\u0438\u043c, \u0434\u0430\u0436\u0435 \u044d\u0442\u043e \u043d\u0435 \u043e\u0441\u043e\u0431\u043e \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u2014 GC \u0441 \u043f\u043e\u043a\u043e\u043b\u0435\u043d\u0438\u044f\u043c\u0438 \u0440\u0443\u043b\u044f\u0442, \u0436\u0438\u0432\u0438 \u0431\u044b\u0441\u0442\u0440\u043e, \u0443\u043c\u0440\u0438 \u043c\u043e\u043b\u043e\u0434\u044b\u043c.<\/p>\n<p>  <\/p>\n<p>\u041a\u0430\u043a \u043d\u0430\u0441\u0447\u0451\u0442 \u043d\u0430\u0448\u0438\u0445 \u0441\u0442\u0430\u0440\u044b\u0445 \u0434\u043e\u0431\u0440\u044b\u0445 \u0434\u0440\u0443\u0437\u0435\u0439?<br \/>  \u0421\u0442\u0440\u043e\u0433\u043e\u0441\u0442\u044c \u0443\u043c\u0435\u043d\u044c\u0448\u0430\u0435\u0442 \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0434\u043e <strong><em>4.1 \u0441\u0435\u043a\u0443\u043d\u0434\u044b<\/em><\/strong>. \u0421\u0431\u043e\u0440\u043a\u0430 \u0447\u0435\u0440\u0435\u0437 LLVM \u0432\u044b\u0438\u0433\u0440\u044b\u0432\u0430\u0435\u0442 \u0435\u0449\u0451 0.4 \u0441\u0435\u043a\u0443\u043d\u0434\u044b, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044f \u0434\u043e\u0441\u0442\u0438\u0447\u044c \u0441\u0443\u043c\u043c\u0430\u0440\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432 <strong><em>3.7 \u0441\u0435\u043a\u0443\u043d\u0434<\/em><\/strong>.<\/p>\n<p>  <\/p>\n<p>\u041d\u0435\u0442, \u0441\u043f\u0430\u0441\u0438\u0431\u043e, \u044f \u043b\u0443\u0447\u0448\u0435 \u043e\u0441\u0442\u0430\u043d\u0443\u0441\u044c \u0441 \u0447\u0438\u0441\u0442\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0435\u0439.<\/p>\n<p>  <\/p>\n<p>\u041d\u043e \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u043c.<\/p>\n<p>  <\/p>\n<h2 id=\"yavnaya-hvostovaya-rekursiya\">\u042f\u0432\u043d\u0430\u044f \u0445\u0432\u043e\u0441\u0442\u043e\u0432\u0430\u044f \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u044f<\/h2>\n<p>  <\/p>\n<p>\u0415\u0441\u0442\u044c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0441\u0432\u0438\u0434\u0435\u0442\u0435\u043b\u044c\u0441\u0442\u0432 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e GHC \u043e\u0447\u0435\u043d\u044c \u043b\u044e\u0431\u0438\u0442 \u0445\u0432\u043e\u0441\u0442\u043e\u0432\u0443\u044e \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u044e, \u0442\u0430\u043a \u0447\u0442\u043e \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0435\u0440\u0435\u043f\u0438\u0448\u0435\u043c \u043d\u0430\u0448 \u043a\u043e\u0434 \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0430 \u0431\u044b\u043b\u0430 \u044f\u0432\u043d\u043e\u0439. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u0443\u0431\u0440\u0430\u0442\u044c \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440 <code>forM_<\/code> \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434:<\/p>\n<p>  <\/p>\n<pre><code class=\"haskell\">import qualified Data.Array.Base as A(unsafeRead, unsafeWrite) import qualified Data.Array.ST as A import qualified Data.ByteString.Char8 as BS import Control.Monad.ST  levenshteinDistance :: BS.ByteString -&gt; BS.ByteString -&gt; Int levenshteinDistance s1 s2 = runST $ do   v0Init &lt;- A.newListArray (0, n) [0..]   v1Init &lt;- A.newArray_ (0, n)   loop 0 v0Init v1Init   A.unsafeRead (if even m then v0Init else v1Init) n    where     m = BS.length s1     n = BS.length s2      loop :: Int -&gt; A.STUArray s Int Int -&gt; A.STUArray s Int Int -&gt; ST s ()     loop i v0 v1 | i == m = pure ()                  | otherwise = do       A.unsafeWrite v1 0 (i + 1)       let s1char = s1 `BS.index` i       let go j | j == n = pure ()                | otherwise = do             delCost &lt;- v0 `A.unsafeRead` (j + 1)             insCost &lt;- v1 `A.unsafeRead` j             substCostBase &lt;- v0 `A.unsafeRead` j             let substCost = if s1char == s2 `BS.index` j then 0 else 1             A.unsafeWrite v1 (j + 1) $ min (substCost + substCostBase) $ 1 + min delCost insCost             go (j + 1)       go 0       loop (i + 1) v1 v0<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u044d\u0442\u043e\u0433\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430 \u2014 <strong><em>4.3 \u0441\u0435\u043a\u0443\u043d\u0434\u044b<\/em><\/strong>. \u0421\u0442\u0440\u043e\u0433\u043e\u0441\u0442\u044c \u0441\u043d\u0438\u0436\u0430\u0435\u0442 \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0434\u043e <strong><em>1.7 \u0441\u0435\u043a\u0443\u043d\u0434<\/em><\/strong> \u2014 \u043f\u0440\u044f\u043c\u043e \u043a\u0430\u043a \u0441 \u0432\u0435\u043a\u0442\u043e\u0440\u0430\u043c\u0438 \u0441 \u043d\u0435\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0439 \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u0446\u0438\u0435\u0439. \u0415\u0441\u043b\u0438 \u0447\u0435\u0441\u0442\u043d\u043e, \u044f \u0443\u0434\u0438\u0432\u043b\u0451\u043d \u0438 \u043e\u0431\u0435\u0441\u043a\u0443\u0440\u0430\u0436\u0435\u043d \u0442\u0435\u043c, \u0447\u0442\u043e GHC \u043d\u0435 \u0441\u043c\u043e\u0433 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c <code>forM_<\/code> \u0442\u0430\u043a \u0436\u0435 \u0445\u043e\u0440\u043e\u0448\u043e, \u043a\u0430\u043a \u043e\u043d \u0441\u043c\u043e\u0433 \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441 \u0445\u0432\u043e\u0441\u0442\u043e\u0432\u043e\u0439 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0435\u0439.<\/p>\n<p>  <\/p>\n<p>\u041d\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0441 LLVM.<\/p>\n<p>  <\/p>\n<p><strong><em>0.96 \u0441\u0435\u043a\u0443\u043d\u0434<\/em><\/strong>. \u0428\u0442\u0430? \u0411\u044b\u0441\u0442\u0440\u0435\u0435 \u0447\u0435\u043c C++? \u042f \u0433\u0434\u0435-\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043b \u043e\u0448\u0438\u0431\u043a\u0443?<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/5f1\/694\/74f\/5f169474f7a3100bf8027711072e2a8c.jpg\">  <\/p>\n<p><strong><em>0.96 \u0441\u0435\u043a\u0443\u043d\u0434<\/em><\/strong>.<\/p>\n<p>  <\/p>\n<p>\u041d\u043e \u043c\u043e\u0436\u043d\u043e \u043b\u0443\u0447\u0448\u0435.<\/p>\n<p>  <\/p>\n<h2 id=\"vsyakaya-meloch\">\u0412\u0441\u044f\u043a\u0430\u044f \u043c\u0435\u043b\u043e\u0447\u044c<\/h2>\n<p>  <\/p>\n<p>\u041c\u044b \u0432\u0441\u0451 \u0435\u0449\u0451 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e \u0447\u0438\u0442\u0430\u0435\u043c \u0441\u0442\u0440\u043e\u043a\u0438 (\u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u0431\u044b\u043b \u044d\u0442\u043e \u043f\u043e\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043f\u0440\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0438 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438, \u0430 \u043f\u043e\u0442\u043e\u043c \u0431\u044b\u043b\u043e \u043b\u0435\u043d\u044c \u043f\u0435\u0440\u0435\u0434\u0435\u043b\u044b\u0432\u0430\u0442\u044c \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0438).<\/p>\n<p>  <\/p>\n<p>\u0417\u0430\u043c\u0435\u043d\u0430 <code>BS.index<\/code> \u043d\u0430 <code>BS.unsafeIndex<\/code> \u0441\u0440\u0435\u0437\u0430\u0435\u0442 \u0435\u0449\u0451 0.04 \u0441\u0435\u043a\u0443\u043d\u0434\u044b, \u0434\u0430\u0432\u0430\u044f \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0432 <strong><em>0.92 \u0441\u0435\u043a\u0443\u043d\u0434\u044b<\/em><\/strong>.<\/p>\n<p>  <\/p>\n<p>\u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0435\u0441\u0442\u044c \u0435\u0449\u0451 \u043e\u0434\u043d\u0430 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c. \u0417\u0430\u043c\u0435\u0442\u0438\u043c, \u0447\u0442\u043e \u043c\u044b \u043f\u0438\u0448\u0435\u043c \u0432 <code>v1[j+1]<\/code> \u043d\u0430 <code>j<\/code>-\u043e\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438 \u0438 \u0447\u0438\u0442\u0430\u0435\u043c \u0438\u0437 \u0442\u043e\u0433\u043e \u0436\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0438. \u0427\u0442\u043e \u0431\u0443\u0434\u0435\u0442, \u0435\u0441\u043b\u0438 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u044f\u0432\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0439 \u0432\u044b\u0437\u043e\u0432?<\/p>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">\u0421\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"haskell\">{-# LANGUAGE Strict #-} {-# OPTIONS_GHC -fllvm #-}  import qualified Data.Array.Base as A(unsafeRead, unsafeWrite) import qualified Data.Array.ST as A import qualified Data.ByteString as BS import qualified Data.ByteString.Unsafe as BS import Control.Monad.ST  levenshteinDistance :: BS.ByteString -&gt; BS.ByteString -&gt; Int levenshteinDistance s1 s2 = runST $ do   v0Init &lt;- A.newListArray (0, n) [0..]   v1Init &lt;- A.newArray_ (0, n)   loop 0 v0Init v1Init   A.unsafeRead (if even m then v0Init else v1Init) n    where     m = BS.length s1     n = BS.length s2      loop :: Int -&gt; A.STUArray s Int Int -&gt; A.STUArray s Int Int -&gt; ST s ()     loop i v0 v1 | i == m = pure ()                  | otherwise = do       A.unsafeWrite v1 0 (i + 1)       let s1char = s1 `BS.unsafeIndex` i       let go j prev | j == n = pure ()                     | otherwise = do             delCost &lt;- v0 `A.unsafeRead` (j + 1)             substCostBase &lt;- v0 `A.unsafeRead` j             let substCost = if s1char == s2 `BS.unsafeIndex` j then 0 else 1             let res = min (substCost + substCostBase) $ 1 + min delCost prev             A.unsafeWrite v1 (j + 1) res             go (j + 1) res       go 0 (i + 1)       loop (i + 1) v1 v0<\/code><\/pre>\n<\/div>\n<\/div>\n<p>  <\/p>\n<p>\u042d\u0442\u0430 \u043c\u0438\u043a\u0440\u043e\u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u0434\u0430\u0451\u0442 \u043d\u0430\u043c \u043f\u0440\u0438\u043c\u0440\u0435\u043d\u043e 0.09 \u0441\u0435\u043a\u0443\u043d\u0434, \u0443\u043c\u0435\u043d\u044c\u0448\u0430\u044f \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0434\u043e <strong><em>0.83 \u0441\u0435\u043a\u0443\u043d\u0434<\/em><\/strong>. \u042d\u0442\u043e \u043f\u043e\u0431\u0435\u0434\u0430.<\/p>\n<p>  <\/p>\n<p>\u0418\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u0447\u0442\u043e \u0430\u043d\u0430\u043b\u043e\u0433 \u044d\u0442\u043e\u0439 \u043c\u0438\u043a\u0440\u043e\u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u043b\u044f C++ \u043d\u0438 \u043d\u0430 \u0447\u0442\u043e \u043d\u0435 \u0432\u043b\u0438\u044f\u0435\u0442.<\/p>\n<p>  <\/p>\n<p>\u042f \u0434\u0443\u043c\u0430\u044e, \u0447\u0442\u043e \u044d\u0442\u043e \u0443\u0436\u0435 \u0432\u043f\u043e\u043b\u043d\u0435 \u043d\u0435\u043f\u043b\u043e\u0445\u043e (\u0438 \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u043d\u0435 \u0442\u0430\u043a \u0443\u0436 \u0443\u0436\u0430\u0441\u043d\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442, \u0442\u0435\u043c \u0431\u043e\u043b\u0435\u0435, \u0447\u0442\u043e \u043d\u0430 \u0432\u0441\u0451 \u044f \u043f\u043e\u0442\u0440\u0430\u0442\u0438\u043b \u043d\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 \u0447\u0430\u0441\u0430). \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0435\u0440\u0435\u0439\u0434\u0451\u043c \u043a \u0438\u0442\u043e\u0433\u043e\u0432\u044b\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u043c \u0438 \u0433\u0440\u0430\u0444\u0438\u043a\u0430\u043c.<\/p>\n<p>  <\/p>\n<h1 id=\"rezultaty\">\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b<\/h1>\n<p>  <\/p>\n<h2 id=\"nakolennye-benchmarki\">\u041d\u0430\u043a\u043e\u043b\u0435\u043d\u043d\u044b\u0435 \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0438<\/h2>\n<p>  <\/p>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u0432\u0435\u0434\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0432\u0441\u0435\u0445 \u043d\u0430\u043a\u043e\u043b\u0435\u043d\u043d\u044b\u0445 \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u043e\u0432 \u0432 \u043e\u0434\u043d\u0443 \u0442\u0430\u0431\u043b\u0438\u0446\u0443. \u0411\u0430\u0437\u043e\u0432\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u0434\u043b\u044f C++-\u0432\u0435\u0440\u0441\u0438\u0438 \u2014 1.36 \u0441\u0435\u043a\u0443\u043d\u0434, \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0430 \u043e\u0442\u043d\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0435\u0433\u043e (\u0442\u0430\u043a \u0447\u0442\u043e \u043e\u043d\u043e \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 100%).<\/p>\n<p>  <\/p>\n<div class=\"scrollable-table\">\n<table>\n<thead>\n<tr>\n<th>\u0412\u0435\u0440\u0441\u0438\u044f<\/th>\n<th>\u0411\u0430\u0437\u043e\u0432\u043e\u0435 \u0432\u0440\u0435\u043c\u044f<\/th>\n<th>+ \u0441\u0442\u0440\u043e\u0433\u043e\u0441\u0442\u044c<\/th>\n<th>+ LLVM<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>\u0427\u0438\u0441\u0442\u0430\u044f<\/td>\n<td>406%<\/td>\n<td>250%<\/td>\n<td>154%<\/td>\n<\/tr>\n<tr>\n<td>\u0427\u0438\u0441\u0442\u0430\u044f (unsafe-\u0438\u043d\u0434\u0435\u043a\u0441\u0430\u0446\u0438\u044f)<\/td>\n<td>309%<\/td>\n<td>181%<\/td>\n<td>121%<\/td>\n<\/tr>\n<tr>\n<td>\u041c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u044b\u0439 \u043c\u0430\u0441\u0441\u0438\u0432<\/td>\n<td>435%<\/td>\n<td>298%<\/td>\n<td>274%<\/td>\n<\/tr>\n<tr>\n<td>\u041c\u0430\u0441\u0441\u0438\u0432 + \u0445\u0432\u043e\u0441\u0442\u043e\u0432\u0430\u044f \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u044f<\/td>\n<td>318%<\/td>\n<td>129%<\/td>\n<td>70%<\/td>\n<\/tr>\n<tr>\n<td>\u041c\u0430\u0441\u0441\u0438\u0432 + \u0445\u0432\u043e\u0441\u0442\u043e\u0432\u0430\u044f \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u044f + \u043c\u0438\u043a\u0440\u043e\u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0438<\/td>\n<td>\u2014<\/td>\n<td>\u2014<\/td>\n<td>61%<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>  <\/p>\n<p>\u0423 \u043c\u0435\u043d\u044f \u0442\u0430\u043a\u0436\u0435 \u0431\u044b\u043b\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u043e\u0433\u043d\u0430\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0437 \u0442\u0435\u0441\u0442\u043e\u0432 \u043d\u0430 \u043c\u0430\u0448\u0438\u043d\u0435 \u0441 i7-6700, \u0438 \u0434\u0432\u0435 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0432\u0430\u0436\u043d\u044b\u0435 \u0442\u043e\u0447\u043a\u0438 \u0442\u0430\u043a\u043e\u0432\u044b:<\/p>\n<p>  <\/p>\n<ul>\n<li>178% \u0434\u043b\u044f \u0447\u0438\u0441\u0442\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u0441 \u043d\u0435\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0439 \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u0446\u0438\u0435\u0439, <\/li>\n<li>84% \u0434\u043b\u044f \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u041f\u043e\u0445\u043e\u0436\u0435, \u0447\u0442\u043e Haskell \u0431\u043b\u0438\u0436\u0435 \u043a Haswell, \u0447\u0435\u043c \u043a Skylake. \u0425\u043e\u0442\u044f, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u0434\u0430\u0436\u0435 \u043d\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u043c \u043d\u0430\u0438\u0431\u044b\u0441\u0442\u0440\u0435\u0439\u0448\u0430\u044f Haskell-\u0432\u0435\u0440\u0441\u0438\u044f \u0431\u044b\u0441\u0442\u0440\u0435\u0435 C++.<\/p>\n<p>  <\/p>\n<h2 id=\"rezultaty-criterion\">\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b criterion<\/h2>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u0432\u0435\u0434\u0451\u043c \u0441\u043a\u0440\u0438\u043d\u0448\u043e\u0442\u044b \u0433\u0440\u0430\u0444\u0438\u043a\u043e\u0432 criterion (\u0443\u0432\u044b, JavaScript \u0442\u0443\u0442 \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u043d\u0435\u043b\u044c\u0437\u044f, \u0442\u0430\u043a \u0447\u0442\u043e \u043e\u043d\u0438 \u043d\u0435\u0436\u0438\u0432\u044b\u0435).<\/p>\n<p>  <\/p>\n<p>\u041d\u0430 Haswell (i7 4770):<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/7w\/_b\/ww\/7w_bwwdokaljtjrvnzkm-rtckoi.png\"><\/p>\n<p>  <\/p>\n<p>\u041d\u0430 Skylake (i7 6700):<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/lm\/c7\/bw\/lmc7bwhwdb5hrmq4bpczxbz3oa0.png\"><\/p>\n<p>  <\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0430\u0441\u044c C++-\u0432\u0435\u0440\u0441\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 FFI. \u041e\u0434\u043d\u0430\u043a\u043e \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u043f\u043b\u044e\u0441-\u043c\u0438\u043d\u0443\u0441 \u0440\u0430\u0432\u043d\u044b\u043c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u00ab\u0447\u0438\u0441\u0442\u043e\u0439\u00bb C++-\u0432\u0435\u0440\u0441\u0438\u0438 \u0431\u0435\u0437 \u0432\u0441\u044f\u043a\u043e\u0433\u043e FFI, \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u0447\u0438\u0442\u0430\u0442\u044c, \u0447\u0442\u043e \u0440\u0430\u0441\u0445\u043e\u0434\u0430\u043c\u0438 \u043d\u0430 FFI \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u043d\u0435\u0431\u0440\u0435\u0447\u044c (\u0434\u0430 \u0438 \u044d\u0442\u043e\u0433\u043e \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043b\u043e \u0431\u044b \u043e\u0436\u0438\u0434\u0430\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u044f \u0438\u0437 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0432 \u043f\u0430\u043c\u044f\u0442\u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f <code>ByteString<\/code>).<\/p>\n<p>  <\/p>\n<h1 id=\"zaklyuchenie\">\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h1>\n<p>  <\/p>\n<ul>\n<li>\u041d\u0430 \u0447\u0438\u0441\u0442\u043e\u043c, \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0438\u0434\u0438\u043e\u043c\u0430\u0442\u0438\u0447\u043d\u043e\u043c \u0445\u0430\u0441\u043a\u0435\u043b\u0435 \u0432\u043f\u043e\u043b\u043d\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0441\u0442\u0438\u0447\u044c \u043d\u0435 \u043d\u0430\u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0443\u0436 \u0434\u0430\u043b\u0435\u043a\u043e \u043e\u0442\u0441\u0442\u043e\u044f\u0449\u0435\u0439 \u043e\u0442 C++ \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<\/li>\n<li>\u0421\u0442\u0440\u043e\u0433\u043e\u0441\u0442\u044c (\u0432\u0435\u0440\u043d\u0435\u0435, \u0435\u0451 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435) \u0432\u0430\u0436\u043d\u0430.<\/li>\n<li>\u0425\u0432\u043e\u0441\u0442\u043e\u0432\u0430\u044f \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u044f \u0432\u0430\u0436\u043d\u0430. GHC, \u0443\u0432\u044b, \u043d\u0435 \u0441\u043f\u043e\u0441\u043e\u0431\u0435\u043d \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0449\u0438 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u044b \u0447\u0435\u0440\u0435\u0437 \u0445\u0432\u043e\u0441\u0442\u043e\u0432\u0443\u044e \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u044e, \u0438 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043e\u0431\u044a\u044f\u0441\u043d\u044f\u0442\u044c \u0435\u043c\u0443 \u044d\u0442\u043e \u0432\u0440\u0443\u0447\u043d\u0443\u044e. \u0422\u0430\u043a \u0447\u0442\u043e \u043f\u0440\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0442\u044f\u0436\u0451\u043b\u044b\u0445 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u0432 \u0442\u043e\u0447\u043d\u043e \u0441\u0442\u043e\u0438\u0442 \u0443\u0434\u0435\u043b\u0438\u0442\u044c \u044d\u0442\u043e\u043c\u0443 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435.<\/li>\n<li>LLVM \u0432\u0430\u0436\u0435\u043d. \u042f \u043d\u0435\u0447\u0430\u0441\u0442\u043e \u0432\u0438\u0434\u0435\u043b, \u0447\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 LLVM \u0434\u0430\u0432\u0430\u043b\u043e \u0442\u0430\u043a\u043e\u0439 \u043f\u0440\u043e\u0444\u0438\u0442 \u0434\u0430\u0436\u0435 \u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0447\u0438\u0441\u043b\u043e\u0434\u0440\u043e\u0431\u0438\u043b\u044c\u043d\u044b\u0445 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430\u0445, \u0442\u0430\u043a \u0447\u0442\u043e \u043f\u0440\u0438\u044f\u0442\u043d\u043e \u0432\u0438\u0434\u0435\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0443, \u0433\u0434\u0435 \u043e\u0442 \u044d\u0442\u043e\u0433\u043e \u0435\u0441\u0442\u044c \u043f\u0440\u043e\u043a.<\/li>\n<li>\u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u2014 \u0441\u0442\u0440\u043e\u0433\u043e \u043d\u0435\u043b\u0438\u043d\u0435\u0439\u043d\u044b\u0439 \u043f\u0440\u043e\u0446\u0435\u0441\u0441. \u041d\u0435\u043b\u044c\u0437\u044f \u043e\u0436\u0438\u0434\u0430\u0442\u044c, \u0447\u0442\u043e \u043e\u0434\u043d\u043e \u0438 \u0442\u043e \u0436\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 (\u0434\u0430\u0436\u0435 \u043e\u0447\u0435\u043d\u044c \u00ab\u0442\u0435\u0445\u043d\u0438\u0447\u0435\u0441\u043a\u043e\u0435\u00bb \u0432\u0440\u043e\u0434\u0435 \u0441\u0442\u0440\u043e\u0433\u043e\u0441\u0442\u0438 \u0438\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0431\u0435\u043a\u0435\u043d\u0434\u0430) \u0434\u0430\u0441\u0442 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u043f\u0440\u0438\u0440\u043e\u0441\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0434\u043b\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0444\u043e\u0440\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u043e\u043a \u0434\u0430\u0436\u0435 \u043e\u0434\u043d\u043e\u0433\u043e \u0438 \u0442\u043e\u0433\u043e \u0436\u0435 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430.<br \/>  \u0412 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438, \u0431\u044b\u043b \u0441\u043e\u0431\u043b\u0430\u0437\u043d \u0434\u0430\u0436\u0435 \u043d\u0435 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c <code>Data.Array.ST<\/code> \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043c\u044b \u0443\u0432\u0438\u0434\u0435\u043b\u0438, \u043a\u0430\u043a \u043f\u043b\u043e\u0445\u043e \u043e\u043d \u0441\u0435\u0431\u044f \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 \u0447\u0438\u0441\u0442\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0435\u0439, \u043d\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u043e\u043d \u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f \u043f\u043e\u0431\u0435\u0434\u0438\u0442\u0435\u043b\u0435\u043c.<\/li>\n<\/ul>\n<p>  <\/p>\n<h1 id=\"vsyakoe-raznoe\">\u0412\u0441\u044f\u043a\u043e\u0435 \u0440\u0430\u0437\u043d\u043e\u0435<\/h1>\n<p>  <\/p>\n<p>\u041e \u0447\u0451\u043c \u044f \u0443\u043c\u043e\u043b\u0447\u0430\u043b \u0432 \u043f\u043e\u0441\u0442\u0435?<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0412 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u043d\u0430 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043c\u0435\u0442\u0430-\u0443\u0440\u043e\u0432\u043d\u0435 \u0440\u0430\u0441\u0441\u0443\u0436\u0434\u0435\u043d\u0438\u0439, \u044d\u0442\u043e \u0438\u0441\u0442\u043e\u0440\u0438\u044f \u0443\u0441\u043f\u0435\u0445\u0430. \u042d\u0442\u043e\u0442 \u043f\u043e\u0441\u0442 \u043d\u0435 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u0445\u0430\u0441\u043a\u0435\u043b\u044c \u0432\u0441\u0435\u0433\u0434\u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c C++-\u0432\u0435\u0440\u0441\u0438\u0438. \u041c\u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0432 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e\u043c \u0441\u043c\u044b\u0441\u043b\u0435 \u043f\u043e\u0432\u0435\u0437\u043b\u043e \u043d\u0430\u0442\u043e\u043b\u043a\u043d\u0443\u0442\u044c\u0441\u044f \u043d\u0430 \u0437\u0430\u0434\u0430\u0447\u0443, \u0433\u0434\u0435 \u044d\u0442\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0442\u0430\u043a. \u041e\u043a\u0430\u0436\u0438\u0441\u044c \u044d\u0442\u043e \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u0442\u0430\u043a, \u044d\u0442\u043e\u0442 \u043f\u043e\u0441\u0442 \u043d\u0435 \u0431\u044b\u043b \u0431\u044b \u0442\u0430\u043a\u0438\u043c \u0440\u0430\u0434\u043e\u0441\u0442\u043d\u044b\u043c (\u0438\u043b\u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u0431\u044b\u043b \u0431\u044b).<\/li>\n<li>\u0418\u043c\u043f\u043e\u0440\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0445 \u0441\u0442\u0440\u043e\u043a \u0432\u0430\u0436\u0435\u043d. <code>Data.ByteString.Char8<\/code> \u043d\u0435\u043d\u0430\u043c\u043d\u043e\u0433\u043e, \u043d\u043e \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u043d\u0430\u0447\u0438\u043c\u043e \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435, \u0447\u0435\u043c <code>Data.ByteString<\/code>.<\/li>\n<li>\u0412\u0435\u0440\u0441\u0438\u044f GHC \u0432\u0430\u0436\u043d\u0430. \u0418\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0435 \u044d\u0442\u043e\u0433\u043e, \u0432\u043f\u0440\u043e\u0447\u0435\u043c, \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0435\u0449\u0451 \u043e\u0434\u043d\u043e \u0438\u0437\u043c\u0435\u0440\u0435\u043d\u0438\u0435 \u0432 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0435 \u044d\u0442\u043e\u0433\u043e \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0430.<br \/>  \u041a\u043e\u0434 \u0432 \u044d\u0442\u043e\u043c \u043f\u043e\u0441\u0442\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043b\u0441\u044f \u043f\u0440\u0438 \u043f\u043e\u043c\u043e\u0449\u0438 GHC 8.6 (Stackage LTS 14.16). GHC 8.8 (\u0441 \u043e\u0434\u043d\u0438\u043c \u0438\u0437 nightly-\u0441\u043d\u0430\u043f\u0448\u043e\u0442\u043e\u0432 Stackage), \u043f\u043e\u0445\u043e\u0436\u0435, \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0431\u043e\u043b\u0435\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u043a\u043e\u0434 \u043f\u0440\u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0441 NCG, \u043d\u043e \u0432 \u0441\u0440\u0435\u0434\u043d\u0435\u043c \u043f\u0440\u043e\u0438\u0433\u0440\u044b\u0432\u0430\u0435\u0442 \u043f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 LLVM. \u041e\u0434\u043d\u0430\u043a\u043e, \u044d\u0442\u043e \u043d\u0435 \u0432\u043b\u0438\u044f\u0435\u0442 \u043d\u0430 \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0431\u044b\u0441\u0442\u0440\u044b\u0439 \u0438\u0437 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432.<\/li>\n<li>\u0417\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0435 \u0442\u0438\u043f\u044b, \u0431\u043b\u0438\u043d, \u0432\u0430\u0436\u043d\u044b. \u041d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0432 \u043f\u043e\u0441\u0442\u0435 \u044f \u044d\u0442\u043e \u0443\u0436\u0435 \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u043b, \u043d\u043e \u043d\u0435 \u043c\u043e\u0433\u0443 \u043d\u0435 \u043f\u043e\u0434\u0447\u0435\u0440\u043a\u043d\u0443\u0442\u044c \u044d\u0442\u043e \u0435\u0449\u0451 \u0440\u0430\u0437. \u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u043f\u0438\u0441\u0430\u0442\u044c <code>unsafe<\/code> \u0442\u0430\u043c, \u0433\u0434\u0435 \u0432 \u0431\u043e\u043b\u0435\u0435 \u0432\u044b\u0440\u0430\u0437\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u043c \u044f\u0437\u044b\u043a\u0435 \u0432\u043f\u043e\u043b\u043d\u0435 \u0432\u0441\u0451 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0438 \u0438\u0437\u0431\u0430\u0432\u0438\u0442\u044c\u0441\u044f \u043e\u0442 \u0440\u0430\u043d\u0442\u0430\u0439\u043c-\u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a, \u043d\u0435 \u043f\u043e\u0442\u0435\u0440\u044f\u0432 \u0432 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u0438 \u2014 \u044d\u0442\u043e \u0443\u0436\u0430\u0441\u043d\u043e, \u044d\u0442\u043e \u043a\u0430\u043a \u043b\u043e\u043f\u0430\u0442\u0430 \u0434\u0432\u043e\u0440\u043d\u0438\u043a\u0430 \u043f\u043e \u0430\u0441\u0444\u0430\u043b\u044c\u0442\u0443 \u0437\u0438\u043c\u043e\u0439.<\/li>\n<li>\u0415\u0449\u0451 \u043e\u0434\u0438\u043d \u0430\u0441\u043f\u0435\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u044b\u043b\u043e \u0431\u044b \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u2014 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043d\u0430 \u0431\u043e\u043b\u0435\u0435 \u0448\u0438\u0440\u043e\u043a\u043e\u043c \u043d\u0430\u0431\u043e\u0440\u0435 \u0432\u0445\u043e\u0434\u043e\u0432. \u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0438\u0442\u0435\u0440\u0430\u0446\u0438\u0439 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u043d\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445, \u0432\u0440\u044f\u0434 \u043b\u0438 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0434\u0432\u0443\u0445 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0445 (\u0438\u043b\u0438 \u0434\u0432\u0443\u0445 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0440\u0430\u0437\u043d\u044b\u0445) \u0441\u0442\u0440\u043e\u043a \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0440\u0435\u043f\u0440\u0435\u0437\u0435\u043d\u0442\u0430\u0442\u0438\u0432\u043d\u044b\u0439 \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a.<\/li>\n<li>\u041c\u0438\u043a\u0440\u043e\u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0430 \u0432\u0430\u0436\u043d\u0430. \u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e, \u043f\u043e\u043c\u0438\u043c\u043e \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u0442\u043e\u0439 \u0440\u0430\u0437\u043d\u0438\u0446\u044b \u043c\u0435\u0436\u0434\u0443 Haswell \u0438 Skylake, \u044f \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b \u0440\u0435\u043f\u043e\u0440\u0442 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e C++-\u043a\u043e\u0434 \u0438 \u0445\u0430\u0441\u043a\u0435\u043b\u044c-\u043a\u043e\u0434 \u0438\u0434\u0443\u0442 \u0432\u0440\u043e\u0432\u0435\u043d\u044c \u043d\u0430 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u0430\u0448\u0438\u043d\u0430\u0445. \u0423 \u043c\u0435\u043d\u044f \u044d\u0442\u043e \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c, \u0438 \u0442\u043e\u0442 \u0440\u0435\u043f\u043e\u0440\u0442 \u0431\u044b\u043b \u043e\u0442 \u043e\u0431\u043b\u0430\u0434\u0430\u0442\u0435\u043b\u044f Ryzen, \u0442\u0430\u043a \u0447\u0442\u043e \u044f \u0432\u0438\u043d\u044e AMD.<br \/>  \u041d\u0443 \u0438 \u0434\u0430\u0436\u0435 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u0430\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u2014 \u044d\u0442\u043e \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u043a\u0440\u0443\u0442\u043e.<\/li>\n<li>\u041d\u0430\u0432\u0435\u0440\u043d\u044f\u043a\u0430 \u043d\u0430\u0448\u0430 \u0431\u0430\u0437\u043e\u0432\u0430\u044f C++-\u0432\u0435\u0440\u0441\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0435\u0449\u0451 \u0431\u043e\u043b\u0435\u0435 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u0430, \u043d\u043e \u044f \u043d\u0435 \u0445\u043e\u0447\u0443 \u0442\u0440\u0430\u0442\u0438\u0442\u044c \u043d\u0430 \u044d\u0442\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u0447\u0435\u043c \u044f \u043f\u043e\u0442\u0440\u0430\u0442\u0438\u043b \u043d\u0430 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044e \u0445\u0430\u0441\u043a\u0435\u043b\u044c-\u0432\u0435\u0440\u0441\u0438\u0438 (\u0438\u043d\u0430\u0447\u0435 \u0442\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u0432\u0441\u044f\u043a\u0438\u0439 \u0441\u043c\u044b\u0441\u043b \u2014 \u0438 \u043d\u0430 \u0445\u0430\u0441\u043a\u0435\u043b\u0435 \u043c\u043e\u0436\u043d\u043e \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c LLVM IR, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440).<\/li>\n<li>\u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u044f \u043f\u043e\u043b\u0443\u0447\u0438\u043b \u0440\u0435\u043f\u043e\u0440\u0442 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0437\u0430\u043c\u0435\u043d\u0430 <code>std::min<\/code> \u043d\u0430 \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0435 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0443\u043b\u0443\u0447\u0448\u0430\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c. \u041c\u043d\u0435 \u044d\u0442\u043e \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438, \u043d\u043e \u0441 \u0434\u0432\u043e\u044f\u043a\u0438\u043c\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u043c\u0438: gcc \u0437\u0430\u043c\u0435\u0434\u043b\u044f\u0435\u0442\u0441\u044f \u0435\u0449\u0451 \u0431\u043e\u043b\u044c\u0448\u0435, \u0434\u043e 1.4-1.5 \u0441\u0435\u043a\u0443\u043d\u0434, \u0430 clang \u0440\u0435\u0437\u043a\u043e \u0443\u0441\u043a\u043e\u0440\u044f\u0435\u0442\u0441\u044f \u2014 \u0434\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e 0.84 \u0441, \u0447\u0442\u043e \u0432\u043f\u043e\u043b\u043d\u0435 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 GHC.<br \/>  \u0412\u043f\u0440\u043e\u0447\u0435\u043c, \u0440\u0430\u0437\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u0435 <code>std::min<\/code> \u0443\u0441\u043a\u043e\u0440\u044f\u0435\u0442 \u0438 \u0445\u0430\u0441\u043a\u0435\u043b\u044c-\u0432\u0435\u0440\u0441\u0438\u044e, \u0438 \u044d\u0442\u043e \u043d\u0435 \u0442\u0430 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u043c\u0435\u0435\u0442 \u0441\u043c\u044b\u0441\u043b \u0432 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435 \u043f\u043e\u0441\u0442\u0430.<\/li>\n<li>\u0418, \u043d\u0430\u043a\u043e\u043d\u0435\u0446, \u0432\u0445\u043e\u0434\u043d\u044b\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 \u0432\u0430\u0436\u043d\u044b. \u042f \u0441\u0434\u0435\u043b\u0430\u043b \u043f\u0430\u0440\u0443 \u0435\u0449\u0451 \u0431\u043e\u043b\u0435\u0435 \u043d\u0430\u043a\u043e\u043b\u0435\u043d\u043d\u044b\u0445 \u0442\u0435\u0441\u0442\u043e\u0432 \u043d\u0430 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0445 \u0441\u0442\u0440\u043e\u043a\u0430\u0445, \u0438 \u0447\u0442\u043e \u0445\u0430\u0441\u043a\u0435\u043b\u044c-, \u0447\u0442\u043e C++-\u0432\u0435\u0440\u0441\u0438\u044f \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0437\u0430\u043c\u0435\u0434\u043b\u0438\u043b\u0438\u0441\u044c. \u041d\u043e \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u043e \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0430\u0442\u044c \u0441\u043e \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u043c\u0438, \u0434\u0430 \u0435\u0449\u0451 \u043c\u0435\u0436\u0434\u0443 \u0434\u0432\u0443\u043c\u044f \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u044f\u0437\u044b\u043a\u0430\u043c\u0438, \u0434\u0430 \u0441 \u043f\u0440\u0438\u0446\u0435\u043b\u043e\u043c \u043d\u0430 \u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0430 \u0435\u0449\u0451 \u043f\u0430\u0440\u0443 \u0434\u044e\u0436\u0438\u043d \u044f\u0437\u044b\u043a\u043e\u0432 (\u0441\u043c. \u043d\u0438\u0436\u0435) \u0441\u043b\u043e\u0436\u043d\u043e, \u0434\u0430 \u0438 \u0441\u043c\u044b\u0441\u043b \u043f\u043e\u0441\u0442\u0430 \u043d\u0435 \u0432 \u044d\u0442\u043e\u043c.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0422\u0430\u043a \u0447\u0442\u043e \u0432\u043e\u0441\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0439\u0442\u0435 \u044d\u0442\u043e\u0442 \u043f\u043e\u0441\u0442 \u0441 \u0434\u043e\u043b\u0435\u0439 \u0441\u043a\u0435\u043f\u0442\u0438\u0446\u0438\u0437\u043c\u0430.<\/p>\n<p>  <\/p>\n<h1 id=\"ssylki\">\u0421\u0441\u044b\u043b\u043a\u0438<\/h1>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/0xd34df00d.me\/pristine\/2020-01-03-fast-edit-distance-criterion-report-haswell.html\" rel=\"nofollow\">\u041f\u043e\u043b\u043d\u044b\u0439 \u043e\u0442\u0447\u0451\u0442 criterion (Haswell)<\/a><\/li>\n<li><a href=\"https:\/\/0xd34df00d.me\/pristine\/2020-01-03-fast-edit-distance-criterion-report-skylake.html\" rel=\"nofollow\">\u041f\u043e\u043b\u043d\u044b\u0439 \u043e\u0442\u0447\u0451\u0442 criterion (Skylake)<\/a><\/li>\n<li><a href=\"https:\/\/github.com\/0xd34df00d\/edit-distance-linear-bench\" rel=\"nofollow\">\u041a\u043e\u0434 \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0430<\/a><\/li>\n<\/ul>\n<p>  <\/p>\n<h1 id=\"bonus\">\u0411\u043e\u043d\u0443\u0441<\/h1>\n<p>  <\/p>\n<p>\u0410 \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u0447\u043d\u0451\u043c \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0443\u044e \u043e\u043b\u0438\u043c\u043f\u0438\u0430\u0434\u0443 \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u0434\u0440\u0443\u0433\u0438\u0435 \u044f\u0437\u044b\u043a\u0438 \u0441\u043f\u0440\u0430\u0432\u044f\u0442\u0441\u044f \u0441 \u044d\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435\u0439. \u041c\u0435\u0442\u043e\u0434\u0438\u043a\u0430 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u0442\u0430 \u0436\u0435 \u2014 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0442\u0440\u0438\u0436\u0434\u044b, \u0431\u0435\u0440\u0451\u043c \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435.<\/p>\n<p>  <\/p>\n<p>\u0421\u043a\u0430\u0436\u0443 \u0441\u0440\u0430\u0437\u0443 \u2014 \u044f \u043d\u0438 \u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u0438\u0437 \u043d\u0438\u0445 \u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0435 \u0443\u043c\u0435\u044e (\u043a\u0440\u043e\u043c\u0435 C++), \u0442\u0430\u043a \u0447\u0442\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u043f\u0440\u043e \u043d\u0438\u0445 \u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043d\u0435 \u043c\u043e\u0433\u0443. \u0421 \u044d\u0442\u0438\u043c\u0438 \u0432\u0441\u0435\u043c\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f\u043c\u0438 \u043c\u043d\u0435 \u043f\u043e\u043c\u043e\u0433 <a href=\"https:\/\/habr.com\/ru\/users\/xrevan86\/\" class=\"user_link\">XRevan86<\/a> \u2014 \u0447\u0443\u0432\u0430\u043a \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u043f\u043e\u043b\u0438\u0433\u043b\u043e\u0442 \u0438 \u0444\u0430\u043d\u0430\u0442 \u0441\u0432\u043e\u0435\u0433\u043e \u0434\u0435\u043b\u0430, \u0442\u0430\u043a \u0447\u0442\u043e \u043f\u043e\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u0439\u0442\u0435\u0441\u044c, \u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u043b\u0430\u0439\u043a.<\/p>\n<p>  <\/p>\n<p>\u041a\u043e\u0434 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0435\u0442 \u0441\u0442\u0440\u043e\u043a\u0438 \u0434\u043b\u0438\u043d\u043e\u0439 15 \u0442\u044b\u0441\u044f\u0447 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432, \u0430 \u043d\u0435 20, \u043e\u0434\u043d\u0430\u043a\u043e \u0447\u0438\u0441\u043b\u0430 \u043f\u0435\u0440\u0435\u043d\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0434\u043b\u044f \u0434\u043b\u0438\u043d\u044b \u0432 20 \u0442\u044b\u0441\u044f\u0447 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432.<\/p>\n<p>  <\/p>\n<p>\u041c\u044b \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u043c\u044b\u0435 \u044f\u0437\u044b\u043a\u0438 (\u043a\u0443\u0434\u0430 \u043c\u044b \u0442\u0430\u043a\u0436\u0435 \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u0438 \u0445\u043e\u043b\u0438\u0432\u0430\u0440\u0430 \u0432\u043a\u043b\u044e\u0447\u0438\u043c Java \u0438 C#) \u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u2014 \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u0435.<\/p>\n<p>  <\/p>\n<h2 id=\"kompiliruemye-yazyki\">\u041a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u043c\u044b\u0435 \u044f\u0437\u044b\u043a\u0438<\/h2>\n<p>  <\/p>\n<p>C++-\u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d \u0434\u043b\u044f \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f. \u0415\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0435\u0449\u0451 \u043d\u0435\u043c\u043d\u043e\u0433\u043e (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0440\u0430\u0437\u0432\u0435\u0440\u043d\u0443\u0432 \u0440\u0443\u043a\u0430\u043c\u0438 <code>std::min<\/code> \u0438\u043b\u0438 \u0437\u0430\u043c\u0435\u043d\u0438\u0432 <code>std::vector<\/code>\/<code>std::string<\/code> \u043d\u0430 \u0441\u044b\u0440\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435), \u043d\u043e \u0442\u043e\u0433\u0434\u0430 \u044d\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f C \u0441 \u043f\u043b\u044e\u0441\u043e\u0432\u044b\u043c main&#8217;\u043e\u043c, \u0447\u0442\u043e \u043d\u0435 \u0442\u0430\u043a \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e. \u0415\u0441\u043b\u0438 \u0431\u044b \u044f \u043f\u0438\u0441\u0430\u043b \u043d\u0430\u0443\u0447\u043d\u0443\u044e \u0440\u0430\u0431\u043e\u0442\u0443, \u044f \u0431\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u00about of scope of this work\u00bb.<\/p>\n<p>  <\/p>\n<p>\u0421-\u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0441 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u044f\u043c\u0438 2000-\u043e\u0433\u043e \u0433\u043e\u0434\u0430 (BCC 5.5) \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d \u0434\u043b\u044f \u043b\u0443\u043b\u0437\u043e\u0432. \u0414\u0440\u0443\u0433\u0438\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u044b \u0434\u043b\u044f \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u0438 \u0435\u0433\u043e \u043e\u043f\u0446\u0438\u0439.<\/p>\n<p>  <\/p>\n<div class=\"scrollable-table\">\n<table>\n<thead>\n<tr>\n<th>\u042f\u0437\u044b\u043a<\/th>\n<th>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f<\/th>\n<th>\u041e\u0442\u043d. \u0432\u0440\u0435\u043c\u044f<\/th>\n<th>\u0410\u0431\u0441. \u0432\u0440\u0435\u043c\u044f, \u0441<\/th>\n<th>\u041e\u043f\u0446\u0438\u0438 \u0442\u0443\u043b\u0447\u0435\u0439\u043d\u0430<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Go<\/td>\n<td>go 1.13<\/td>\n<td>106%<\/td>\n<td>0.876<\/td>\n<td><code>-compiler gc -gcflags=-B -ldflags '-w -s'<\/code><\/td>\n<\/tr>\n<tr>\n<td>\u0421<\/td>\n<td>clang 9<\/td>\n<td>106%<\/td>\n<td>0.877<\/td>\n<td><code>-O3 -march=native<\/code><\/td>\n<\/tr>\n<tr>\n<td>Rust<\/td>\n<td>rustc 1.38<\/td>\n<td>124%<\/td>\n<td>1.028<\/td>\n<td><code>-C debuginfo=0 -C opt-level=3<\/code><\/td>\n<\/tr>\n<tr>\n<td>\u0421<\/td>\n<td>gcc 9.2<\/td>\n<td>125%<\/td>\n<td>1.038<\/td>\n<td><code>-Ofast -fPIC -fPIE -static -flto<\/code><\/td>\n<\/tr>\n<tr>\n<td>Zig<\/td>\n<td>zig 0.5<\/td>\n<td>125%<\/td>\n<td>1.040<\/td>\n<td><code>--release-fast -fPIC --strip -target x86_64-linux-gnu build-exe<\/code><\/td>\n<\/tr>\n<tr>\n<td>Java<\/td>\n<td>openjdk 1.8.0<\/td>\n<td>125%<\/td>\n<td>1.040<\/td>\n<td><code>-g:none<\/code><\/td>\n<\/tr>\n<tr>\n<td>\u0421<\/td>\n<td>clang 9<\/td>\n<td>132%<\/td>\n<td>1.096<\/td>\n<td><code>-Ofast -fPIC -fPIE -static -flto<\/code><\/td>\n<\/tr>\n<tr>\n<td>Crystal<\/td>\n<td>crystal 0.32<\/td>\n<td>152%<\/td>\n<td>1.262<\/td>\n<td><code>--release<\/code><\/td>\n<\/tr>\n<tr>\n<td>C++<\/td>\n<td>gcc 9.2<\/td>\n<td>163%<\/td>\n<td>1.356<\/td>\n<td><code>-O3 -march=native<\/code><\/td>\n<\/tr>\n<tr>\n<td>D<\/td>\n<td>dmd 2.087<\/td>\n<td>182%<\/td>\n<td>1.515<\/td>\n<td><code>-fPIC -boundscheck=safeonly -O -release<\/code><\/td>\n<\/tr>\n<tr>\n<td>Pascal<\/td>\n<td>fpc 3.0<\/td>\n<td>183%<\/td>\n<td>1.520<\/td>\n<td><code>-Mfpc -O3 -Cg XX -Xg -Xs -k-flto<\/code><\/td>\n<\/tr>\n<tr>\n<td>\u0421<\/td>\n<td>bcc 5.5<\/td>\n<td>190%<\/td>\n<td>1.581<\/td>\n<td><\/td>\n<\/tr>\n<tr>\n<td>Nim<\/td>\n<td>nim 1.0.2<\/td>\n<td>223%<\/td>\n<td>1.851<\/td>\n<td><code>-d:release --opt:speed --checks:off --passc:-flto --passc:-s<\/code><\/td>\n<\/tr>\n<tr>\n<td>C++<\/td>\n<td>clang 9<\/td>\n<td>323%<\/td>\n<td>2.684<\/td>\n<td><code>-O3 -march=native<\/code><\/td>\n<\/tr>\n<tr>\n<td>C#<\/td>\n<td>Mono 6.6.0<\/td>\n<td>356%<\/td>\n<td>2.967<\/td>\n<td><code>mcs -o+<\/code><\/td>\n<\/tr>\n<tr>\n<td>C#<\/td>\n<td>.NET core 3.1<\/td>\n<td>721%<\/td>\n<td>5.984<\/td>\n<td><code>\u00af\\_(\u30c4)_\/\u00af<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>  <\/p>\n<p>\u041d\u0430\u0431\u043b\u044e\u0434\u0435\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<ul>\n<li>nim&#8217;\u0443 \u043f\u043e\u043a\u0430 \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u0431\u0435\u0434\u0438\u0442\u044c Borland C++ Compiler, \u0432\u044b\u043f\u0443\u0449\u0435\u043d\u043d\u044b\u0439 \u0432 2000-\u043c \u0433\u043e\u0434\u0443. \u0423\u0432\u044b.<\/li>\n<li>\u0420\u0430\u0437\u043d\u0438\u0446\u0430 \u043c\u0435\u0436\u0434\u0443 Java \u0438 C# \u043a\u0430\u043a\u0430\u044f-\u0442\u043e \u043e\u0433\u0440\u043e\u043c\u043d\u0430\u044f, \u0438 Java \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u043e\u0437\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0431\u043b\u0438\u0437\u043a\u043e \u043a \u0432\u0435\u0440\u0448\u0438\u043d\u0435, \u0445\u043e\u0442\u044f \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u043b <code>javac -g:none LevDist.java &amp;&amp; java LevDist<\/code>. \u041d\u0430\u0432\u0435\u0440\u043d\u043e\u0435, \u0442\u0443\u0442 \u0447\u0442\u043e-\u0442\u043e \u0441\u043e\u0432\u0441\u0435\u043c \u043d\u0435 \u0442\u0430\u043a. \u0425\u043e\u0442\u044f, \u0441 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u044d\u0442\u043e \u043e\u0447\u0435\u043d\u044c JIT-friendly-\u0437\u0430\u0434\u0430\u0447\u0430, \u0442\u0430\u043a \u0447\u0442\u043e, \u043c\u043e\u0436\u0435\u0442, \u0437\u0434\u0435\u0441\u044c JIT \u0442\u0432\u043e\u0440\u0438\u0442 \u0447\u0443\u0434\u0435\u0441\u0430.<\/li>\n<li>\u0415\u0449\u0451 \u043b\u044e\u0431\u043e\u043f\u044b\u0442\u043d\u043e, \u0447\u0442\u043e clang \u0443\u043c\u0443\u0434\u0440\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u0447\u0438\u0441\u0442\u0443\u044e \u0441\u043b\u0438\u0432\u0430\u0442\u044c \u043d\u0430 C++-\u043a\u043e\u0434\u0435, \u043d\u043e \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0432\u044b\u0440\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0432\u043f\u0435\u0440\u0451\u0434 \u043d\u0430 \u0421-\u043a\u043e\u0434\u0435.<\/li>\n<li>C# \u0441 .NET Core \u0443 \u043c\u0435\u043d\u044f \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c, \u0438 \u044f \u0432\u0437\u044f\u043b \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b <a href=\"https:\/\/habr.com\/ru\/users\/xrevan86\/\" class=\"user_link\">XRevan86<\/a>, \u043e\u0442\u043d\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0432 \u0438\u0445 \u043d\u0430 \u0440\u0430\u0437\u043d\u0438\u0446\u0443 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0435\u0439 \u043d\u0430\u0448\u0438\u0445 \u043c\u0430\u0448\u0438\u043d \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430\u043c. \u041d\u0430\u0443\u0447\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u0448\u043a\u0430\u043b\u0438\u0432\u0430\u0435\u0442, \u043f\u043e\u043d\u0438\u043c\u0430\u044e.<\/li>\n<li>\u0412\u0435\u0437\u0434\u0435 \u043a\u0443\u0447\u0430 \u0430\u043d\u0441\u0435\u0439\u0444\u0430. \u0418\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u043d \u0432\u043b\u0438\u044f\u0435\u0442 \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 \u044f\u0437\u044b\u043a\u0430\u0445?<\/li>\n<li>\u0412 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f\u0445 (\u043f\u043e \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043c\u0435\u0440\u0435, \u0432 \u0421++) \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u043f\u043e\u0440\u044f\u0434\u043a\u0430 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0439. \u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u2014 \u0438\u043c\u0445\u043e \u0441\u043a\u043e\u0440\u0435\u0435 \u0447\u0438\u0442\u0435\u0440\u0441\u0442\u0432\u043e \u0438 \u0441\u043d\u043e\u0432\u0430 out of scope. <\/li>\n<li>\u041f\u0440\u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0438\u0437 \u044d\u0442\u0438\u0445 \u043f\u043e\u0440\u044f\u0434\u043a\u043e\u0432 \u043c\u043d\u0435 \u0442\u0430\u043a\u0438 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u0435 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 C++. \u0422\u0430\u043a, \u0435\u0441\u043b\u0438 \u0432\u043c\u0435\u0441\u0442\u043e <code>std::min({ delCost, insCost, substCost })<\/code> \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c <code>std::min(substCost, std::min(delCost, insCost))<\/code>, \u0442\u043e \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u043e\u0434 gcc <em>\u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f<\/em> \u0434\u043e 1.440 \u0441\u0435\u043a\u0443\u043d\u0434, \u0430 \u043f\u043e\u0434 clang \u2014 <em>\u0443\u043c\u0435\u043d\u044c\u0448\u0430\u0435\u0442\u0441\u044f<\/em> \u0434\u043e 0.840 \u0441\u0435\u043a\u0443\u043d\u0434 (\u0443\u0440\u0430, \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0432\u0441\u0435\u0445 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u0438 \u043f\u043e\u0447\u0442\u0438 \u0445\u0430\u0441\u043a\u0435\u043b\u044c). \u041f\u043e\u0445\u043e\u0436\u0435, clang \u043d\u0435 \u043b\u044e\u0431\u0438\u0442 initializer lists \u0438 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0438\u0445 \u0437\u0430\u0438\u043d\u043b\u0430\u0439\u043d\u0438\u0442\u044c, \u0430 gcc \u0448\u0435\u0434\u0443\u043b\u0438\u0442 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0438 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u044b \u0442\u0430\u043a, \u0447\u0442\u043e, \u043f\u043e \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043c\u0435\u0440\u0435, \u043d\u0430 \u044d\u0442\u0438\u0445 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0440\u043e\u0438\u0433\u0440\u044b\u0432\u0430\u0435\u0442.<br \/>  \u041d\u043e \u0435\u0449\u0451 \u0440\u0430\u0437 \u043e\u0442\u043c\u0435\u0447\u0443, \u0447\u0442\u043e \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u043f\u043e\u0440\u044f\u0434\u043a\u0430 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0445\u0430\u0441\u043a\u0435\u043b\u044f \u044f \u043d\u0435 \u0437\u0430\u043d\u0438\u043c\u0430\u043b\u0441\u044f, \u0438 \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c\u0441\u044f \u044d\u0442\u0438\u043c \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u044d\u0442\u043e\u0433\u043e \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0430 \u043d\u0435 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u044e \u0432 \u043b\u044e\u0431\u043e\u043c \u044f\u0437\u044b\u043a\u0435.<br \/>  \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e \u043d\u0435\u043b\u044c\u0437\u044f \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u043d\u0430 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0434\u0430\u0436\u0435 \u0432 \u0442\u0430\u043a\u043e\u043c \u044f\u0437\u044b\u043a\u0435, \u043a\u0430\u043a C++, \u0433\u0434\u0435 \u0432 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u044b \u0432\u043b\u0438\u0442\u044b \u0434\u0435\u0441\u044f\u0442\u043a\u0438 \u0442\u044b\u0441\u044f\u0447 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u043e\u043b\u0435\u0442.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0421\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043a\u043e\u0434 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">C<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cpp\">#include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;string.h&gt; #include &lt;time.h&gt;  static long lev_dist (const char *s1,           const char *s2) {     unsigned long m, n;     unsigned long i, j;     long *v0, *v1;     long ret, *temp;      m = strlen (s1);     n = strlen (s2);      \/* Edge cases. *\/     if (m == 0) {         return n;     } else if (n == 0) {         return m;     }      v0 = malloc (sizeof (long) * (n + 1));     v1 = malloc (sizeof (long) * (n + 1));      if (v0 == NULL || v1 == NULL) {         fprintf (stderr, \"failed to allocate memory\\n\");         exit (-1);     }      for (i = 0; i &lt;= n; ++i) {         v0[i] = i;     }     memcpy (v1, v0, n + 1);      for (i = 0; i &lt; m; ++i) {         v1[0] = i + 1;          for (j = 0; j &lt; n; ++j) {             const long subst_cost = (s1[i] == s2[j]) ? v0[j] : (v0[j] + 1);             const long del_cost = v0[j + 1] + 1;             const long ins_cost = v1[j] + 1;  #if !defined(__GNUC__) || defined(__llvm__)             if (subst_cost &lt; del_cost) {                 v1[j + 1] = subst_cost;             } else {                 v1[j + 1] = del_cost;             } #else             v1[j + 1] = (subst_cost &lt; del_cost) ? subst_cost : del_cost; #endif             if (ins_cost &lt; v1[j + 1]) {                 v1[j + 1] = ins_cost;             }         }          temp = v0;         v0 = v1;         v1 = temp;     }      ret = v0[n];     free (v0);     free (v1);     return ret; }  int main () {     const int len = 15000;     int i;     char s1[15001], *s2 = s1, s3[15001];     clock_t start_time, exec_time;      for (i = 0; i &lt; len; ++i) {         s1[i] = 'a';         s3[i] = 'b';     }     s1[len] = s3[len] = '\\0';      start_time = clock ();      printf (\"%ld\\n\", lev_dist (s1, s2));     printf (\"%ld\\n\", lev_dist (s1, s3));      exec_time = clock () - start_time;     fprintf (stderr,              \"Finished in %.3fs\\n\",              ((double) exec_time) \/ CLOCKS_PER_SEC);     return 0; } <\/code><\/pre>\n<\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Crystal<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"ruby\">def lev_dist(s1 : String, s2 : String) : Int   m = s1.bytesize   n = s2.bytesize    # Edge cases.   return n if m == 0   return m if n == 0    v0 = (Slice.new(n + 1) { |i| i }).to_unsafe   v1 = (Slice.new(n + 1) { |i| i }).to_unsafe    ca1, ca2 = s1.bytes, s2.bytes    ca1.each_with_index do |c1, i|     v1[0] = i + 1      ca2.each_with_index do |c2, j|       subst_cost = (c1 == c2) ? v0[j] : (v0[j] + 1)       del_cost = v0[j + 1] + 1       ins_cost = v1[j] + 1        # [del_cost, ins_cost, subst_cost].min is slow.       min_cost = (subst_cost &lt; del_cost) ? subst_cost : del_cost       if ins_cost &lt; min_cost         min_cost = ins_cost       end       v1[j + 1] = min_cost     end      v0, v1 = v1, v0   end    return v0[n] end  s1 = \"a\" * 15_000 s2 = s1 s3 = \"b\" * 15_000  exec_time = -Time.monotonic.to_f  puts lev_dist(s1, s2) puts lev_dist(s1, s3)  exec_time += Time.monotonic.to_f STDERR.puts \"Finished in #{\"%.3f\" % exec_time}s\"<\/code><\/pre>\n<\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">C#<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"cs\">using System; using System.Diagnostics; using System.Linq; using System.Text;  public class Program {     public static Int32 LevDist(string s1, string s2)     {         var ca1 = Encoding.UTF8.GetBytes(s1);         var ca2 = Encoding.UTF8.GetBytes(s2);         return LevDist(ca1, ca2);     }      public static Int32 LevDist(byte[] s1, byte[] s2)     {         var m = s1.Length;         var n = s2.Length;          \/\/ Edge cases.         if (m == 0)         {             return n;         }         else if (n == 0)         {             return m;         }          Int32[] v0 = Enumerable.Range(0, n + 1).ToArray();         var v1 = new Int32[n + 1];          v0.CopyTo(v1, 0);          for (var i = 0; i &lt; m; ++i)         {             v1[0] = i + 1;              for (var j = 0; j &lt; n; ++j)             {                 var substCost = (s1[i] == s2[j]) ? v0[j] : (v0[j] + 1);                 var delCost = v0[j + 1] + 1;                 var insCost = v1[j] + 1;                  v1[j + 1] = Math.Min(substCost, delCost);                 if (insCost &lt; v1[j + 1])                 {                     v1[j + 1] = insCost;                 }             }              var temp = v0;             v0 = v1;             v1 = temp;         }          return v0[n];     }      public static int Main()     {         string s1 = new String('a', 15000);         string s2 = s1;         string s3 = new String('b', 15000);          Stopwatch execTimer = new Stopwatch();         execTimer.Start();          Console.WriteLine(LevDist(s1, s2));         Console.WriteLine(LevDist(s1, s3));          execTimer.Stop();         double execTime = execTimer.ElapsedMilliseconds \/ 1000.0;          Console.WriteLine($\"Finished in {execTime:0.000}s\");         return 0;     } }<\/code><\/pre>\n<\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">D<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"plaintext\">module main; import core.time; import std.stdio; import std.algorithm : swap; import std.array : array; import std.range : iota, replicate;  long levDist(ref const string s1,              ref const string s2) pure nothrow @trusted {     const auto m = s1.length;     const auto n = s2.length;      if (m == 0)     {         return n;     }     else if (n == 0)     {         return m;     }      long[] v0 = iota(0, long(n) + 1).array;     long[] v1 = v0.dup;      size_t i = 0;     foreach (ref c1; s1)     {         v1[0] = i + 1;          size_t j = 0;         foreach (ref c2; s2)         {             const auto substCost = (c1 == c2) ? v0[j] : (v0[j] + 1);             const auto delCost = v0[j + 1] + 1;             const auto insCost = v1[j] + 1;              \/\/ min(substCost, delCost, insCost) is slow.             v1[j + 1] = (substCost &lt; delCost) ? substCost : delCost;             if (insCost &lt; v1[j + 1])             {                 v1[j + 1] = insCost;             }              ++j;         }          swap(v0, v1);         ++i;     }      return v0[n]; }  void main(string[] args) {     string s1 = \"a\".replicate(15000);     string s2 = s1;     string s3 = \"b\".replicate(15000);      auto startTime = MonoTime.currTime;      writeln(levDist(s1, s2));     writeln(levDist(s1, s3));      auto endTime = MonoTime.currTime;     auto execTime = (endTime - startTime).total!\"msecs\" \/ 1000.0;      stderr.writefln(\"Finished in %.3fs\", execTime); }<\/code><\/pre>\n<\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Go<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"go\">package main  import (     \"bytes\"     \"fmt\"     \"os\"     \"time\" )  func levDist(s1, s2 []byte) int {      m := len(s1)     n := len(s2)      \/\/ Edge cases.     if m == 0 {         return n     } else if n == 0 {         return m     }      root := make([]int, (n+1)*2)      v0 := root[:n+1]     v1 := root[n+1:]     for i, _ := range v0 {         v0[i] = i     }     copy(v1, v0)      for i, c1 := range s1 {         v1[0] = i + 1          for j, c2 := range s2 {             substCost := v0[j]             if c1 != c2 {                 substCost++             }             delCost := v0[j+1] + 1             insCost := v1[j] + 1              if substCost &lt; delCost {                 v1[j+1] = substCost             } else {                 v1[j+1] = delCost             }             if insCost &lt; v1[j+1] {                 v1[j+1] = insCost             }         }          v0, v1 = v1, v0     }      return v0[n] }  func main() {      s1 := bytes.Repeat([]byte(\"a\"), 15000)     s2 := s1     s3 := bytes.Repeat([]byte(\"b\"), 15000)      startTime := time.Now()      fmt.Println(levDist(s1, s2))     fmt.Println(levDist(s1, s3))          execTime := time.Now().Sub(startTime).Seconds()     fmt.Fprintf(os.Stderr, \"Finished in %.3fs\\n\", execTime) }<\/code><\/pre>\n<\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Rust<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"rust\">use std::cmp::min; use std::time::Instant;  fn lev_dist(s1: &amp;str, s2: &amp;str) -&gt; i32 {     let m = s1.len();     let n = s2.len();      \/\/ Edge cases.     if m == 0 {         return n as i32;     } else if n == 0 {         return m as i32;     }      let mut v0: Vec&lt;i32&gt; = (0..).take(n + 1).collect();     let mut v1 = v0.to_vec();      for (i, c1) in s1.bytes().enumerate() {         unsafe {             *v1.get_unchecked_mut(0) = i as i32 + 1;              for (j, c2) in s2.bytes().enumerate() {                 let mut subst_cost = *v0.get_unchecked(j);                 if c1 != c2 {                     subst_cost += 1;                 }                 let del_cost = *v0.get_unchecked(j + 1) + 1;                 let ins_cost = *v1.get_unchecked(j) + 1;                  let mut min_cost = min(subst_cost, del_cost);                 if ins_cost &lt; min_cost {                     min_cost = ins_cost;                 }                 *v1.get_unchecked_mut(j + 1) = min_cost;             }         }          std::mem::swap(&amp;mut v0, &amp;mut v1);     }      return v0[n]; }  fn main() {     let s1 = \"a\".repeat(15000);     let s2 = &amp;s1;     let s3 = \"b\".repeat(15000);      let start_time = Instant::now();      println!(\"{}\", lev_dist(&amp;s1, &amp;s2));     println!(\"{}\", lev_dist(&amp;s1, &amp;s3));      let exec_time = start_time.elapsed().as_millis() as f64 \/ 1000.0;     eprintln!(\"Finished in {:.3}s\", exec_time); }<\/code><\/pre>\n<\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Zig<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"plaintext\">const std = @import(\"std\"); const time = std.time; const Allocator = std.mem.Allocator;  pub fn lev_dist(allocator: *Allocator, s1: []const u8, s2: []const u8) !i32 {     @setRuntimeSafety(false);     const m = s1.len;     const n = s2.len;      \/\/ Edge cases.     if (m == 0) {         return @intCast(i32, n);     } else if (n == 0) {         return @intCast(i32, m);     }      var root = try allocator.alloc(i32, (n + 1) * 2);     defer allocator.free(root);      var v0 = root[0..(n + 1)];     var v1 = root[(n + 1)..];      for (v0) |*it, i| {         it.* = @intCast(i32, i);     }     std.mem.copy(i32, v1, v0);      for (s1) |c1, i| {         v1[0] = @intCast(i32, i) + 1;          for (s2) |c2, j| {             const subst_cost = if (c1 == c2) v0[j] else (v0[j] + 1);             const del_cost = v0[j + 1] + 1;             const ins_cost = v1[j] + 1;              \/\/ std.mem.min(i32, [_]i32{subst_cost, del_cost, ins_cost}) is slow.             v1[j + 1] = if (subst_cost &lt; del_cost) subst_cost else del_cost;             if (ins_cost &lt; v1[j + 1]) {                 v1[j + 1] = ins_cost;             }         }          std.mem.swap([]i32, &amp;v0, &amp;v1);     }      return v0[n]; }  pub fn main() !void {     const allocator = std.heap.page_allocator;     const stdout = &amp;(try std.io.getStdOut()).outStream().stream;      const s1 = [_]u8{'a'} ** 15000;     const s2 = s1;     const s3 = [_]u8{'b'} ** 15000;      var exec_timer = try time.Timer.start();      try stdout.print(\"{}\\n\", try lev_dist(allocator, s1, s2));     try stdout.print(\"{}\\n\", try lev_dist(allocator, s1, s3));      const exec_time = @intToFloat(f64, exec_timer.read()) \/ time.ns_per_s;     std.debug.warn(\"Finished in {d:.3}s\\n\", exec_time); }<\/code><\/pre>\n<\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Pascal<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"plaintext\">program main(output); uses   sysutils, dateutils;  function levDist(const s1: AnsiString; const s2: AnsiString): longint;   var     m, n: NativeUint;     i, j: NativeUint;     c1, c2: AnsiChar;     v0, v1, temp: array of longint;     substCost, delCost, insCost: longint;   begin     m := length(s1);     n := length(s2);      \/\/ Edge cases.     if m = 0 then       exit(n)     else if n = 0 then       exit(m);      setLength(v0, n+1);     for i := 0 to n do       v0[i] := i;     v1 := copy(v0, 0, n+1);      i := 0;     for c1 in s1 do       begin         j := 0;         v1[0] := i + 1;          for c2 in s2 do           begin             substCost := v0[j];             if c1 &lt;&gt; c2 then               inc(substCost);             delCost := v0[j+1] + 1;             insCost := v1[j] + 1;              if substCost &lt; delCost then               v1[j+1] := substCost             else               v1[j+1] := delCost;             if insCost &lt; v1[j+1] then               v1[j+1] := insCost;              inc(j);           end;          temp := v0;         v0 := v1;         v1 := temp;          inc(i);       end;      exit(v0[n]);   end;  var   i: integer;   s1, s2, s3: AnsiString;   startTime, execTime: TDateTime; begin   s1 := '';   s3 := '';   for i := 1 to 15000 do     begin       s1 := s1 + 'a';       s3 := s3 + 'b';     end;   s2 := s1;    startTime := now;    writeln(levDist(s1, s2));   writeln(levDist(s1, s3));    execTime := secondSpan(startTime, now);   writeln(stderr, format('Finished in %.3fs', [execTime])); end. <\/code><\/pre>\n<\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Nim<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"plaintext\">import strformat, strutils, times  {.push checks: off.} func levDist(s1, s2: string): int32 =   let m = s1.len   let n = s2.len    # Edge cases.   if m == 0: return int32(n)   elif n == 0: return int32(m)    var v0 = newSeq[int32](n + 1)   for i, _ in v0:     v0[i] = int32(i)    var v1 = v0    for i, c1 in s1:     v1[0] = int32(i) + 1      for j, c2 in s2:       let delCost = v0[j + 1] + 1       let insCost = v1[j] + 1       var substCost = v0[j]       if c1 != c2:         inc(substCost)        # min([substCost, delCost, insCost]) is slow.       v1[j + 1] = min(substCost, delCost)       if insCost &lt; v1[j + 1]:         v1[j + 1] = insCost      swap(v0, v1)    result = v0[n] {.pop.}  let s1 = repeat(\"a\", 15000) let s2 = s1 let s3 = repeat(\"b\", 15000)  let startTime = cpuTime()  echo levDist(s1, s2) echo levDist(s1, s3)  let execTime = cpuTime() - startTime; stderr.write &amp;\"Finished in {execTime:.3f}s\\n\";<\/code><\/pre>\n<\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Java<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"java\">import java.util.Arrays; import java.util.stream.LongStream; import java.lang.Math;  public class LevDist {     public static long levDist(String s1, String s2)     {         return levDist(s1.getBytes(), s2.getBytes());     }      public static long levDist(byte[] s1, byte[] s2)     {         int m = s1.length;         int n = s2.length;          \/\/ Edge cases.         if (m == 0) {             return n;         } else if (n == 0) {             return m;         }          long[] v0 = LongStream.range(0, n + 1).toArray();         long[] v1 = v0.clone();          int i = 0, j;         for (byte c1 : s1) {             v1[0] = i + 1;              j = 0;             for (byte c2 : s2) {                 long substCost = (c1 == c2) ? v0[j] : (v0[j] + 1);                 long delCost = v0[j + 1] + 1;                 long insCost = v1[j] + 1;                  v1[j + 1] = Math.min(substCost, delCost);                 if (insCost &lt; v1[j + 1]) {                     v1[j + 1] = insCost;                 }                  ++j;             }              long[] temp = v0;             v0 = v1;             v1 = temp;              ++i;         }          return v0[n];     }      public static void main(String[] args)     {         byte[] s1 = new byte[15000];         byte[] s2 = s1;         byte[] s3 = new byte[15000];          Arrays.fill(s1, (byte) 'a');         Arrays.fill(s3, (byte) 'b');          long execTime = -System.nanoTime();          System.out.println(levDist(s1, s2));         System.out.println(levDist(s1, s3));          execTime += System.nanoTime();          System.err.printf(\"Finished in %.3fs%n\", execTime \/ 1000000000.0);     } }<\/code><\/pre>\n<\/div>\n<\/div>\n<p>  <\/p>\n<h2 id=\"interpretiruemye-yazyki\">\u0418\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u0435 \u044f\u0437\u044b\u043a\u0438<\/h2>\n<p>  <\/p>\n<div class=\"scrollable-table\">\n<table>\n<thead>\n<tr>\n<th>\u042f\u0437\u044b\u043a<\/th>\n<th>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f<\/th>\n<th>\u041e\u0442\u043d. \u0432\u0440\u0435\u043c\u044f<\/th>\n<th>\u0410\u0431\u0441.\u0432\u0440\u0435\u043c\u044f, \u0441<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Julia<\/td>\n<td>julia 1.3.0<\/td>\n<td>241%<\/td>\n<td>2.00<\/td>\n<\/tr>\n<tr>\n<td>JavaScript<\/td>\n<td>spidermonkey 60.5.2<\/td>\n<td>308%<\/td>\n<td>2.56<\/td>\n<\/tr>\n<tr>\n<td>JavaScript<\/td>\n<td>v8 (node.js 13.3.0)<\/td>\n<td>414%<\/td>\n<td>3.43<\/td>\n<\/tr>\n<tr>\n<td>Python<\/td>\n<td>pypy 7.2.0<\/td>\n<td>978%<\/td>\n<td>8.12<\/td>\n<\/tr>\n<tr>\n<td>Lua<\/td>\n<td>luajit 2.0.5<\/td>\n<td>\u22482890%<\/td>\n<td>24<\/td>\n<\/tr>\n<tr>\n<td>PHP<\/td>\n<td>php 7.4<\/td>\n<td>\u22484670%<\/td>\n<td>39<\/td>\n<\/tr>\n<tr>\n<td>Hack<\/td>\n<td>HHVM 4.39<\/td>\n<td>\u22485100%<\/td>\n<td>43<\/td>\n<\/tr>\n<tr>\n<td>Lua<\/td>\n<td>lua 5.1<\/td>\n<td>\u22488900%<\/td>\n<td>74<\/td>\n<\/tr>\n<tr>\n<td><del>Perl 6<\/del> NQP<\/td>\n<td>nqp 2019.07<\/td>\n<td>\u224811100%<\/td>\n<td>92<\/td>\n<\/tr>\n<tr>\n<td>Ruby<\/td>\n<td>ruby 2.6<\/td>\n<td>\u224812200%<\/td>\n<td>101<\/td>\n<\/tr>\n<tr>\n<td>Perl<\/td>\n<td>perl 5.30<\/td>\n<td>\u224819100%<\/td>\n<td>158<\/td>\n<\/tr>\n<tr>\n<td>Python<\/td>\n<td>python 3.6<\/td>\n<td>\u224827400%<\/td>\n<td>227<\/td>\n<\/tr>\n<tr>\n<td>Python<\/td>\n<td>python 3.8<\/td>\n<td>\u224830000%<\/td>\n<td>249<\/td>\n<\/tr>\n<tr>\n<td><del>Perl 6<\/del> Raku<\/td>\n<td>rakudo 2019.11<\/td>\n<td>\u221e%<\/td>\n<td>\u221e<\/td>\n<\/tr>\n<tr>\n<td>Octave<\/td>\n<td>octave 5.1<\/td>\n<td>\u221e%<\/td>\n<td>\u221e<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>  <\/p>\n<p>\u0421\u043d\u043e\u0432\u0430 \u043d\u0430\u0431\u043b\u044e\u0434\u0435\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u041f\u0440\u0438\u0432\u044b\u0447\u043d\u043e \u0434\u0443\u043c\u0430\u0442\u044c, \u0447\u0442\u043e V8 \u2014 \u0431\u043e\u043b\u0435\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0439 JS-\u0434\u0432\u0438\u0436\u043e\u043a. \u041d\u0435 \u0432 \u044d\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435.<\/li>\n<li>\u041a\u043e\u0435-\u0433\u0434\u0435 \u043c\u044b \u043d\u0435 \u0434\u043e\u0436\u0434\u0430\u043b\u0438\u0441\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 (\u0442\u0430\u043c, \u0433\u0434\u0435 \u0437\u043d\u0430\u0447\u043e\u043a \u221e).<\/li>\n<li>Python \u0434\u043b\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u0442\u0430\u043a \u0441\u0435\u0431\u0435. Pypy \u0443\u0436\u0435 \u043c\u043e\u0436\u043d\u043e, \u043d\u043e \u043b\u0443\u0447\u0448\u0435 \u0432\u0441\u0451-\u0442\u0430\u043a\u0438 Julia.<\/li>\n<li>Octave \u0445\u043e\u0440\u043e\u0448\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 \u043c\u0430\u0442\u0440\u0438\u0446\u0430\u043c\u0438, \u0430 \u0442\u0443\u0442 \u0437\u0430\u0434\u0430\u0447\u0430 \u0438\u043c\u0435\u0435\u0442 \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u043d\u0435\u043c\u0430\u0442\u0440\u0438\u0447\u043d\u0443\u044e \u0444\u043e\u0440\u043c\u0443, \u0442\u0430\u043a \u0447\u0442\u043e \u0443\u0432\u044b. <\/li>\n<li>\u041f\u0440\u043e Raku \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043f\u043e\u0448\u0443\u0442\u0438\u0442\u044c, \u043d\u043e \u043d\u0435 \u0431\u0443\u0434\u0443. \u041c\u043d\u0435 \u0436\u0435 \u043d\u0435 12 \u043b\u0435\u0442, \u0432 \u043a\u043e\u043d\u0446\u0435 \u043a\u043e\u043d\u0446\u043e\u0432.<\/li>\n<\/ul>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Julia<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"julia\">#!\/usr\/bin\/env julia using Base: @pure, stderr using Printf  @pure function lev_dist(s1::AbstractString, s2::AbstractString)::Int32     m, n = sizeof(s1), sizeof(s2)      m == 0 &amp;&amp; return n     n == 0 &amp;&amp; return m      ca1, ca2 = codeunits(s1), codeunits(s2)      v0::Vector{Int32} = collect(0:n)     v1 = copy(v0)      @inbounds begin         for (i, c1) in enumerate(ca1)             v1[1] = i              for (j, c2) in enumerate(ca2)                 subst_cost = v0[j] + ((c1 === c2) ? 0 : 1)                 del_cost = v0[j + 1] + 1                 ins_cost = v1[j] + 1                  v1[j + 1] = min(subst_cost, del_cost, ins_cost)             end             v0, v1 = v1, v0         end     end      return v0[n + 1] end  let     s1 = 'a'^15000     s2 = s1     s3 = 'b'^15000      exec_time = @elapsed begin         println(lev_dist(s1, s2))         println(lev_dist(s1, s3))     end     @printf(stderr, \"Finished in %.3fs\\n\", exec_time) end <\/code><\/pre>\n<\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">JS<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"javascript\">function stringToByteArray(s) {   let a = [];   for (let c of s) {     c = c.charCodeAt(0);     do {       a.unshift(c &amp; 0xFF);       c &gt;&gt;= 8;     } while (c !== 0);   }   return a; }  function levDist(s1, s2) {   if (typeof s1 === \"string\" || s1 instanceof String) {     s1 = stringToByteArray(s1);   }   if (typeof s2 === \"string\" || s2 instanceof String) {     s2 = stringToByteArray(s2);   }    const m = s1.length;   const n = s2.length;    \/\/ Edge cases.   if (m == 0) {     return n;   } else if (n == 0) {     return m;   }    let v0 = [];   for (let i = 0; i &lt;= n; ++i) {     v0[i] = i;   }   let v1 = v0.slice();    for (let i = 0; i &lt; m; ++i) {     v1[0] = i + 1;      for (let j = 0; j &lt; n; ++j) {       const substCost = v0[j] + ((s1[i] === s2[j]) ? 0 : 1);       const delCost = v0[j + 1] + 1;       const insCost = v1[j] + 1;        \/\/ Math.min(substCost, delCost, insCost) is slow.       v1[j + 1] = (substCost &lt; delCost) ? substCost : delCost;       if (insCost &lt; v1[j + 1]) {         v1[j + 1] = insCost;       }     }      [v0, v1] = [v1, v0];   }    return v0[n]; }  var s1 = new Uint8Array(15000); var s2 = s1; var s3 = new Uint8Array(s1.length);  for (let i = 0; i &lt; s1.length; ++i) {     s1[i] = \"a\".charCodeAt(0);     s3[i] = \"b\".charCodeAt(0); }  var execTime = -Date.now();  console.log(levDist(s1, s2)); console.log(levDist(s1, s3));  execTime += Date.now(); console.log(`Finished in ${(execTime \/ 1000).toFixed(3)}s`);<\/code><\/pre>\n<\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Python<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"python\">#!\/usr\/bin\/env python3 import sys import time from typing import AnyStr  def lev_dist(s1: AnyStr, s2: AnyStr) -&gt; int:     if isinstance(s1, str): s1 = s1.encode()     if isinstance(s2, str): s2 = s2.encode()      m = len(s1)     n = len(s2)      # Edge cases.     if m == 0: return n     elif n == 0: return m      v0 = list(range(0, n + 1))     v1 = v0[:]      for i, c1 in enumerate(s1):         v1[0] = i + 1          for j, c2 in enumerate(s2):             subst_cost = v0[j] if c1 == c2 else (v0[j] + 1)             del_cost = v0[j + 1] + 1             ins_cost = v1[j] + 1              # min(subst_cost, del_cost, ins_cost) is slow.             min_cost = subst_cost if subst_cost &lt; del_cost else del_cost             if ins_cost &lt; min_cost:                 min_cost = ins_cost             v1[j + 1] = min_cost          v0, v1 = v1, v0      return v0[n]  if __name__ == \"__main__\":     s1 = b\"a\" * 15_000     s2 = s1     s3 = b\"b\" * 15_000      exec_time = -time.monotonic()      print(lev_dist(s1, s2))     print(lev_dist(s1, s3))      exec_time += time.monotonic()     print(f\"Finished in {exec_time:.3f}s\", file=sys.stderr)<\/code><\/pre>\n<\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Lua<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"lua\">#!\/usr\/bin\/env lua  function levDist (s1, s2)   local m = s1:len()   local n = s2:len()    -- Edge cases   if m == 0 then return n end   if n == 0 then return m end    local ct1, ct2 = {}, {}   for i = 1, #s1 do       ct1[i] = s1:sub(i, i)   end   for i = 1, #s2 do       ct2[i] = s2:sub(i, i)   end    local v0, v1 = {}, {}   for i = 1, n + 1 do     v0[i] = i - 1     v1[i] = i - 1   end    local minCost, substCost, delCost, insCost   for i, c1 in pairs(ct1) do     v1[1] = i      for j, c2 in pairs(ct2) do       substCost = (c1 == c2) and v0[j] or (v0[j] + 1)       delCost = v0[j + 1] + 1       insCost = v1[j] + 1        -- math.min(substCost, delCost, insCost) is slow.       minCost = (substCost &lt; delCost) and substCost or delCost       if insCost &lt; minCost then         minCost = insCost       end       v1[j + 1] = minCost     end      v0, v1 = v1, v0   end    return v0[n + 1] end  s1 = string.rep(\"a\", 15000) s2 = s1 s3 = string.rep(\"b\", 15000)  execTime = -os.clock()  print(levDist(s1, s2)) print(levDist(s1, s3))  execTime = execTime + os.clock() io.stderr:write(string.format(\"Finished in %.3fs\\n\", execTime))<\/code><\/pre>\n<\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">PHP<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">#!\/usr\/bin\/env php &lt;?php  function lev_dist(string $s1, string $s2): int {     $m = strlen($s1);     $n = strlen($s2);      \/\/ Edge cases.     if ($m == 0) {         return $n;     } elseif ($n == 0) {         return $m;     }      $ca1 = $ca2 = [];     for ($i = 0; $i &lt; $m; ++$i) {         $ca1[] = ord($s1[$i]);     }     for ($i = 0; $i &lt; $n; ++$i) {         $ca2[] = ord($s2[$i]);     }      $v0 = range(0, $n + 1);     $v1 = $v0;      foreach ($ca1 as $i =&gt; $c1) {         $v1[0] = $i + 1;          foreach ($ca2 as $j =&gt; $c2) {             $subst_cost = ($c1 == $c2) ? $v0[$j] : ($v0[$j] + 1);             $del_cost = $v0[$j + 1] + 1;             $ins_cost = $v1[$j] + 1;              \/\/ min($subst_cost, $del_cost, $ins_cost) is slow.             $min_cost = ($subst_cost &lt; $del_cost) ? $subst_cost : $del_cost;             if ($ins_cost &lt; $min_cost) {                 $min_cost = $ins_cost;             }             $v1[$j + 1] = $min_cost;         }          [$v0, $v1] = [$v1, $v0];     }      return $v0[$n]; }  $s1 = str_repeat('a', 15000); $s2 = $s1; $s3 = str_repeat('b', 15000);  $exec_time = -hrtime(true);  echo lev_dist($s1, $s2), \"\\n\"; echo lev_dist($s1, $s3), \"\\n\";  $exec_time += hrtime(true); fprintf(STDERR, \"Finished in %.3fs\\n\", $exec_time \/ 1000000000);<\/code><\/pre>\n<\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">HHVM<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">#!\/usr\/bin\/env hhvm  function lev_dist(string $s1, string $s2): int {   $m = \\strlen($s1);   $n = \\strlen($s2);    \/\/ Edge cases.   if ($m == 0) {     return $n;   } else if ($n == 0) {     return $m;   }    $ca1 = $ca2 = vec[];   for ($i = 0; $i &lt; $m; ++$i) {     $ca1[] = \\ord($s1[$i]);   }   for ($i = 0; $i &lt; $n; ++$i) {     $ca2[] = \\ord($s2[$i]);   }    $v0 = vec(\\range(0, $n + 1));   $v1 = $v0;    foreach ($ca1 as $i =&gt; $c1) {     $v1[0] = $i + 1;      foreach ($ca2 as $j =&gt; $c2) {       $subst_cost = ($c1 == $c2) ? $v0[$j] : ($v0[$j] + 1);       $del_cost = $v0[$j + 1] + 1;       $ins_cost = $v1[$j] + 1;        \/\/ \\min($subst_cost, $del_cost, $ins_cost) is slow.       $min_cost = ($subst_cost &lt; $del_cost) ? $subst_cost : $del_cost;       if ($ins_cost &lt; $min_cost) {         $min_cost = $ins_cost;       }       $v1[$j + 1] = $min_cost;     }      list($v0, $v1) = vec[$v1, $v0];   }    return $v0[$n]; }  &lt;&lt;__EntryPoint&gt;&gt; function main(): void {   $s1 = \\str_repeat('a', 15000);   $s2 = $s1;   $s3 = \\str_repeat('b', 15000);    $exec_time = -\\clock_gettime_ns(\\CLOCK_MONOTONIC);    echo lev_dist($s1, $s2), \"\\n\";   echo lev_dist($s1, $s3), \"\\n\";    $exec_time += \\clock_gettime_ns(\\CLOCK_MONOTONIC);   \\fprintf(\\STDERR, \"Finished in %.3fs\\n\", $exec_time \/ 1000000000); }<\/code><\/pre>\n<\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">NQP<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"perl\">#!\/usr\/bin\/env nqp use nqp;  sub str-to-byte-array(str $s) {     my @a;     for nqp::split('', $s) -&gt; $c {         $c := nqp::ord($c);         repeat {             my uint8 $b := $c +&amp; 0xFF;             @a.unshift($b);             $c := nqp::bitshiftr_i($c, 8);         } while $c != 0;     }     return @a; }  sub lev-dist(str $s1, str $s2) {     my @ca1 := str-to-byte-array($s1);     my @ca2 := str-to-byte-array($s2);      my $m := nqp::elems(@ca1);     my $n := nqp::elems(@ca2);      # Edge cases.     return $n if $m == 0;     return $m if $n == 0;      my @v0[$n + 1];     my @v1[$n + 1];      my int $i := 0;     while $i &lt;= $n {         @v0[$i] := $i;         @v1[$i] := $i;         ++$i;     }      $i := 0;     for @ca1 -&gt; $c1 {         @v1[0] := $i + 1;          my int $j := 0;         for @ca2 -&gt; $c2 {             my int $subst-cost := @v0[$j] + (($c1 == $c2) ?? 0 !! 1);             my int $del-cost := @v0[$j + 1] + 1;             my int $ins-cost := @v1[$j] + 1;              my int $min-cost := ($subst-cost &lt; $del-cost) ?? $subst-cost !! $del-cost;             if $ins-cost &lt; $min-cost {                 $min-cost := $ins-cost;             }             @v1[$j + 1] := $min-cost;              ++$j;         }          my @temp := @v0;         @v0 := @v1;         @v1 := @temp;          ++$i;     }      return @v0[$n]; }  sub MAIN(*@ARGS) {     my str $s1 := nqp::x('a', 15_000);     my str $s2 := $s1;     my str $s3 := nqp::x('b', 15_000);      my num $start-time := nqp::time_n();      say(lev-dist($s1, $s2));     say(lev-dist($s1, $s3));      my num $exec-time := nqp::sub_n(nqp::time_n(), $start-time);     stderr().print(nqp::sprintf(\"Finished in %.3fs\\n\", [$exec-time])); }<\/code><\/pre>\n<\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Ruby<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"ruby\">#!\/usr\/bin\/env ruby # encoding: utf-8  def lev_dist(s1, s2)   m = s1.bytesize   n = s2.bytesize    # Edge cases.   return n if m == 0   return m if n == 0    v0 = (0..n).to_a   v1 = v0.dup    ca1, ca2 = s1.bytes, s2.bytes    ca1.each_with_index do |c1, i|     v1[0] = i + 1      ca2.each_with_index do |c2, j|       subst_cost = (c1 == c2) ? v0[j] : (v0[j] + 1)       del_cost = v0[j + 1] + 1       ins_cost = v1[j] + 1        # [del_cost, ins_cost, subst_cost].min is slow.       min_cost = (subst_cost &lt; del_cost) ? subst_cost : del_cost       if ins_cost &lt; min_cost         min_cost = ins_cost       end       v1[j + 1] = min_cost     end      v0, v1 = v1, v0   end    return v0[n] end  s1 = \"a\" * 15_000 s2 = s1 s3 = \"b\" * 15_000  exec_time = -Process.clock_gettime(Process::CLOCK_MONOTONIC)  puts lev_dist(s1, s2) puts lev_dist(s1, s3)  exec_time += Process.clock_gettime(Process::CLOCK_MONOTONIC) STDERR.puts \"Finished in #{\"%.3f\" % exec_time}s\"<\/code><\/pre>\n<\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Raku<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"perl\">#!\/usr\/bin\/env raku =encoding utf8; use v6;  multi lev-dist(Str:D $s1, Str:D $s2 --&gt; Int:D) {     my $ca1 := buf8.new($s1.encode);     my $ca2 := buf8.new($s2.encode);      return lev-dist($ca1, $ca2); }  multi lev-dist(buf8:D $s1, buf8:D $s2 --&gt; Int:D) {     my $m := $s1.bytes;     my $n := $s2.bytes;      # Edge cases.     return $n if $m == 0;     return $m if $n == 0;      my @ca1 = $s1.list;     my @ca2 = $s2.list;      my @v0[$n + 1] = 0..$n;     my @v1[$n + 1] = 0..$n;      for @ca1.kv -&gt; $i, $c1 {         @v1[0] = $i + 1;          for @ca2.kv -&gt; $j, $c2 {             my $subst-cost := @v0[$j] + (($c1 == $c2) ?? 0 !! 1);             my $del-cost := @v0[$j + 1] + 1;             my $ins-cost := @v1[$j] + 1;              # min($subst-cost, $del-cost, $ins-cost) is slow.             my $min-cost := ($subst-cost &lt; $del-cost) ?? $subst-cost !! $del-cost;             if $ins-cost &lt; $min-cost {                 $min-cost = $ins-cost;             }             @v1[$j + 1] = $min-cost;         }          my @temp := @v0;         @v0 := @v1;         @v1 := @temp;     }      return @v0[$n]; }  sub MAIN() {     my $s1 := 'a' x 15_000;     my $s2 := $s1;     my $s3 := 'b' x 15_000;      my $start-time := now;      say(lev-dist($s1, $s2));     say(lev-dist($s1, $s3));      my $exec-time := now - $start-time;     note(sprintf(\"Finished in %.3fs\", $exec-time)); }<\/code><\/pre>\n<\/div>\n<\/div>\n<p>  <\/p>\n<div class=\"spoiler\"><b class=\"spoiler_title\">Octave<\/b><\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"matlab\">#!\/usr\/bin\/env octave 1;  function retval = lev_dist (s1, s2)   if (!isvector (s1) || iscell (s1) || !isvector (s2) || iscell (s2))     error (\"lev_dist: Incompatible types in assignment\");   endif    m = length (s1);   n = length (s2);    if (m == 0)     retval = n;   elseif (n == 0)     retval = m;   else     v0 = [0:n];     v1 = v0;      for i = 1:m       v1(1) = i;        for j = 1:n         subst_cost = v0(j) + (s1(i) != s2(j));         del_cost = v0(j + 1) + 1;         ins_cost = v1(j) + 1;          # min ([subst_cost, del_cost, ins_cost]) is slow.         if (subst_cost &lt; del_cost)           min_cost = subst_cost;         else           min_cost = del_cost;         endif         if (ins_cost &lt; min_cost)           min_cost = ins_cost;         endif         v1(j + 1) = min_cost;       endfor        [v0, v1] = deal (v1, v0);     endfor      retval = v0(n + 1);   endif endfunction  function main ()   s1 = repmat ([\"a\"], 15_000, 1);   s2 = s1;   s3 = repmat ([\"b\"], 15_000, 1);   tic ();   printf (\"%d\\n\", lev_dist (s1, s2));   printf (\"%d\\n\", lev_dist (s1, s3));   exec_time = toc ();   fprintf (stderr, \"Finished in %.3fs\\n\", exec_time); endfunction  main ();<\/code><\/pre>\n<\/div>\n<\/div>\n<p>  <\/p>\n<h1 id=\"zaklyuchenie-okonchatelnoe\">\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 (\u043e\u043a\u043e\u043d\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435)<\/h1>\n<p>  <\/p>\n<p>\u0415\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0432\u0441\u0451 \u044d\u0442\u043e \u043d\u0435 \u0437\u043d\u0430\u0447\u0438\u0442, \u0447\u0442\u043e \u0445\u0430\u0441\u043a\u0435\u043b\u044c \u0440\u0443\u043b\u0438\u0442 \u0438 \u043f\u0435\u0434\u0430\u043b\u0438\u0442 \u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u043e\u0432\u044b\u0439 \u043a\u043e\u0440\u043e\u043b\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438. \u042f \u0432 \u0441\u0432\u043e\u0435\u0439 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u0447\u0430\u0441\u0442\u043e \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u044e\u0441\u044c \u0441\u043e \u0441\u043b\u0443\u0447\u0430\u044f\u043c\u0438, \u043a\u043e\u0433\u0434\u0430 \u043a\u043e\u0434 \u043d\u0430 \u043f\u043b\u044e\u0441\u0430\u0445 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u0435\u0435. \u041e\u0434\u043d\u0430\u043a\u043e, \u0435\u0441\u043b\u0438 \u043c\u043d\u0435 \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043c\u043d\u043e\u0436\u0430\u0442\u044c \u043c\u0430\u0442\u0440\u0438\u0446\u044b (\u0434\u043b\u044f \u0447\u0435\u0433\u043e \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u0438\u0448\u043d\u043e-\u0444\u043e\u0440\u0442\u0440\u0430\u043d\u043d\u044b\u0439 MKL), \u0438 \u0435\u0441\u043b\u0438 \u044f \u043f\u0438\u0448\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 \u0445\u0430\u0441\u043a\u0435\u043b\u0435, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u043c\u0435\u043b\u043e \u0431\u0440\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u0441\u0430\u043c\u044b\u0439 \u0445\u0430\u0441\u043a\u0435\u043b\u044c \u0438 \u043d\u0435 \u0434\u0443\u043c\u0430\u0442\u044c \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u0434\u0435\u043b\u0430\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u044f\u0434\u0440\u0430 \u043d\u0430 \u0421 \u0438 \u043f\u0430\u0440\u0438\u0442\u044c\u0441\u044f \u0441 FFI.<\/p>\n<p>  <\/p>\n<p>\u041d\u0443 \u0438 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c \u043d\u0430 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043d\u0438\u0433\u0434\u0435 \u043d\u0435\u043b\u044c\u0437\u044f.<\/p>\n<p>  <\/p>\n<p>\u0427\u0435\u0433\u043e \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442?<\/p>\n<p>  <\/p>\n<ul>\n<li>\u041e\u043a\u0430\u043c\u043b\u044f \u0438 SML \u0441 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 MLton (\u0433\u043e\u0432\u043e\u0440\u044f\u0442, \u043e\u043d\u0430 \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u0442 \u043f\u043e\u043b\u0447\u0430\u0441\u0430, \u043d\u043e \u0442\u0432\u043e\u0440\u0438\u0442 \u0447\u0443\u0434\u0435\u0441\u0430).<\/li>\n<li>Idris 2 \u0441 uniqueness types. \u042d\u0442\u043e \u0442\u0443\u0442 \u0442\u043e\u0436\u0435 \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0442\u0432\u043e\u0440\u0438\u0442\u044c \u0447\u0443\u0434\u0435\u0441\u0430, \u0431\u0435\u0437\u043e \u0432\u0441\u044f\u043a\u043e\u0439 \u044f\u0432\u043d\u043e\u0439 \u043c\u0443\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 (\u043d\u0443 \u0438 \u0431\u0435\u0437 unsafe, \u0441\u0430\u043c\u043e \u0441\u043e\u0431\u043e\u0439).<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0422\u0430\u043a\u0438\u0435 \u0434\u0435\u043b\u0430.<\/p>\n<\/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=\"https:\/\/habr.com\/ru\/post\/483864\/\"> https:\/\/habr.com\/ru\/post\/483864\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/483864\/\">\n<p>\u041f\u0440\u0438\u0432\u0435\u0442, \u0425\u0430\u0431\u0440.<\/p>\n<p>  <\/p>\n<p>\u0423 \u043c\u0435\u043d\u044f \u0442\u0443\u0442 \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u043e \u043a\u043e\u0434 \u043d\u0430 \u0445\u0430\u0441\u043a\u0435\u043b\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0441\u044f \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u043d\u0430 C++. \u0418\u043d\u043e\u0433\u0434\u0430 \u2014 \u043d\u0430 40%.<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/83\/fd\/a4\/83fda4sz5x37klkngozxiczziwg.png\"><br \/>  <em>(\u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b, \u043c\u0435\u043d\u044c\u0448\u0435 \u2014 \u043b\u0443\u0447\u0448\u0435, C++ \u0441\u043d\u0438\u0437\u0443)<\/em><\/p>\n<p>  <\/p>\n<p>\u0427\u0442\u043e \u0441\u0430\u043c\u043e\u0435 \u0441\u043c\u0435\u0448\u043d\u043e\u0435 \u2014 \u044f \u0441\u043e\u0431\u0438\u0440\u0430\u043b \u0445\u0430\u0441\u043a\u0435\u043b\u044c-\u043a\u043e\u0434 \u0447\u0435\u0440\u0435\u0437 LLVM-\u0431\u0435\u043a\u0435\u043d\u0434, \u043d\u043e \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u043b \u0441 GCC. \u0415\u0441\u043b\u0438 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c \u0441 clang (\u0447\u0442\u043e \u0432\u0440\u043e\u0434\u0435 \u043a\u0430\u043a \u043b\u043e\u0433\u0438\u0447\u043d\u0435\u0435), \u0442\u043e \u0432\u0441\u0451 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0435\u0449\u0451 \u0445\u0443\u0436\u0435 \u0434\u043b\u044f \u043f\u043b\u044e\u0441\u043e\u0432: \u043f\u043e\u0447\u0435\u043c\u0443-\u0442\u043e \u043d\u0430 \u044d\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435 clang \u043f\u0440\u043e\u0438\u0433\u0440\u044b\u0432\u0430\u0435\u0442 GCC \u0432 \u043f\u0430\u0440\u0443 \u0440\u0430\u0437, \u0438 \u0440\u0430\u0437\u043d\u0438\u0446\u0430 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043d\u0435 40%, \u0430 \u044d\u0442\u0430\u043a \u0440\u0430\u0437\u0430 \u0442\u0440\u0438. \u0412\u043f\u0440\u043e\u0447\u0435\u043c, \u043e\u0434\u043d\u0430 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0430\u044f \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f C++-\u043a\u043e\u0434\u0430 \u044d\u0442\u043e \u043f\u043e\u043c\u0435\u043d\u044f\u0435\u0442.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u0447\u0430\u043b\u043e\u0441\u044c \u0432\u0441\u0451 \u0441 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u043c\u043e\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 (\u043a\u043e\u0442\u043e\u0440\u044b\u0439, \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0445\u0430\u0441\u043a\u0435\u043b\u0435, \u0438 \u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u044f \u0442\u043e\u0436\u0435 \u0441\u043a\u043e\u0440\u043e \u043d\u0430\u043f\u0438\u0448\u0443) \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b\u0441\u0442\u0440\u043e \u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u041b\u0435\u0432\u0435\u043d\u0448\u0442\u0435\u0439\u043d\u0430 \u043c\u0435\u0436\u0434\u0443 \u0434\u0432\u0443\u043c\u044f \u0441\u0442\u0440\u043e\u043a\u0430\u043c\u0438. \u0420\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u041b\u0435\u0432\u0435\u043d\u0448\u0442\u0435\u0439\u043d\u0430 \u2014 \u044d\u0442\u043e \u0442\u0430\u043a\u0430\u044f \u043c\u0435\u0442\u0440\u0438\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0433\u043e\u0432\u043e\u0440\u0438\u0442, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u043d\u0443\u0436\u043d\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u044c, \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0438\u043b\u0438 \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0432 \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435, \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0430 \u0441\u0442\u0430\u043b\u0430 \u0440\u0430\u0432\u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435. \u042f \u0441\u0447\u0438\u0442\u0430\u043b \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0438\u043c\u0438 \u0441\u0442\u0440\u043e\u043a\u0430\u043c\u0438 (\u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0430 \u0434\u0435\u0441\u044f\u0442\u043a\u043e\u0432 \u0442\u044b\u0441\u044f\u0447 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432), \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c \u0431\u044b\u043b\u0430 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u0430\u0436\u043d\u0430.<\/p>\n<p>  <\/p>\n<p>\u0410 \u043f\u043e\u0442\u043e\u043c \u043c\u043d\u0435 \u0441\u0442\u0430\u043b\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u043d\u0430\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0431\u044b\u0441\u0442\u0440\u043e \u044f \u0432\u043e\u043e\u0431\u0449\u0435 \u043c\u043e\u0433\u0443 \u044d\u0442\u043e \u0440\u0430\u0441\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0441\u0447\u0438\u0442\u0430\u0442\u044c (\u043f\u043e\u0442\u0440\u0430\u0442\u0438\u0432 \u0440\u0430\u0437\u0443\u043c\u043d\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0430 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u044e, \u043a\u043e\u043d\u0435\u0447\u043d\u043e), \u0442\u0430\u043a \u0447\u0442\u043e \u044f \u043d\u0430\u0431\u0440\u043e\u0441\u0430\u043b \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u043d\u0430 \u0421++ \u0438 \u0432\u0437\u044f\u043b \u0435\u0433\u043e \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0437\u0430 \u044d\u0442\u0430\u043a\u0438\u0439 \u0438\u0434\u0435\u0430\u043b, \u043a \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u0441\u0442\u043e\u0438\u0442 \u0441\u0442\u0440\u0435\u043c\u0438\u0442\u044c\u0441\u044f. \u0412\u043f\u0440\u043e\u0447\u0435\u043c, \u043a\u0430\u043a \u0443\u0436\u0435 \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u0438\u0434\u0435\u0430\u043b \u043e\u043a\u0430\u0437\u0430\u043b\u0441\u044f \u043f\u0440\u0435\u0432\u0437\u043e\u0439\u0434\u0451\u043d.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0441\u0442\u0438\u0447\u044c?<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/b51\/03d\/1b9\/b5103d1b96fa82c7316d26bab06678f8.jpg\"><\/p>\n<p>  <\/p>\n<p>\u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0431\u043e\u043d\u0443\u0441\u0430 \u2014 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0441 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u044f\u0437\u044b\u043a\u0430\u043c\u0438. \u0421\u043f\u043e\u0439\u043b\u0435\u0440\u044b:<\/p>\n<p>  <\/p>\n<ul>\n<li>Nim \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 C \u0434\u0432\u0430\u0434\u0446\u0430\u0442\u0438\u043b\u0435\u0442\u043d\u0435\u0439 \u0434\u0430\u0432\u043d\u043e\u0441\u0442\u0438.<\/li>\n<li>C# \u0432 \u043f\u044f\u0442\u044c \u0440\u0430\u0437 \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435 Java, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u043f\u043e\u043b\u043d\u0435 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 Rust.<\/li>\n<li>Go \u0432\u0440\u043e\u0432\u0435\u043d\u044c \u0441 C.<\/li>\n<li>PHP \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u043f\u0438\u0442\u043e\u043d\u0430 (\u0447\u0442\u043e \u043e\u043f\u0440\u0430\u0432\u0434\u044b\u0432\u0430\u0435\u0442 \u0432\u0442\u043e\u0440\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430).<\/li>\n<\/ul>\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-297121","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/297121","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=297121"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/297121\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=297121"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=297121"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=297121"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}