[00:06:31] <ada_ru> (coopht) так delay вроде бы секунды спит
[00:07:22] <ada_ru> (Максим) Кто сказал? Там дробный аргумент
[00:21:56] <ada_ru> (I_vlxy_I) оно же как раз нанослип юзает
[00:22:04] <ada_ru> (I_vlxy_I)  отвечает (coopht) на <так delay вроде бы с…>
вон, в исходнике видно
[00:24:17] <ada_ru> (coopht) а, точно
[00:24:24] <ada_ru> (coopht) я туплю
[00:24:25] <ada_ru> (coopht) спасибо!
[00:29:17] <ada_ru> (I_vlxy_I)  отвечает (Максим) на <declare
  Stream : …>
А я вот не понял, как через это вывести что-то типа String? Stream.Write(чтосюдаписать?)
[00:29:29] <ada_ru> (I_vlxy_I) допустим у меня есть str : String
[00:38:31] <ada_ru> (I_vlxy_I) Хм. String'Write(Output_Stream, Item); абсолютно идентична по производительности Ada.Text_IO.Put_Line (Item);
[00:49:29] <ada_ru> (I_vlxy_I) В общем, я пока не понимаю как сделать быстрый вывод строк из Ады
[00:56:13] <ada_ru> (coopht) это потому что ада не нужна
[00:58:42] <ada_ru> (I_vlxy_I) попробовал отсюда: https://benchmarksgame-team.pages.debian.net/benchmarksgame/program/revcomp-gnat-2.html

один фиг медленно.
[01:01:34] <OCTAGRAM> I_vlxy_I, declare Item : constant Stream_Elements_Array (1 .. Some_Length) with Import, Address => Some_Address;
[01:04:20] <ada_ru> (I_vlxy_I)  отвечает на <(OCTAGRAM) I_vlxy_I,…>
У меня вот такое скопипасчено:

  procedure Put_Line (Item : String) is
     subtype Index is Stream_Element_Offset range 1 .. Item'Length;
     subtype XBytes is Stream_Element_Array (Index);
     Item_Bytes: XBytes;
     pragma Import (Ada, Item_Bytes);
     for Item_Bytes'Address use Item'Address;
     pragma Assert (Item'Size = Item_Bytes'Size);
  begin
     Output_Stream.Write (Item_Bytes);
     Output_Stream.Write (Separator_Bytes);
  end Put_Line;
[01:05:18] <ada_ru> (I_vlxy_I) если я правильно понимаю, это оно и есть.
[01:06:06] <ada_ru> (I_vlxy_I) и это не быстрее чем просто Ada.Text_IO.Put_Line (Item);
[01:07:16] <ada_ru> (I_vlxy_I) точнее это даже медленнее. если убрать второй write, то будет также как Ada.Text_IO.Put_Line (Item);
[01:07:39] <ada_ru> (I_vlxy_I) Output_Stream : Ada.Text_IO.Text_Streams.Stream_Access :=
    Ada.Text_IO.Text_Streams.Stream (Ada.Text_IO.Standard_Output);
[01:07:51] <ada_ru> (I_vlxy_I) вот что такое аутпут_стрим
[02:03:27] <OCTAGRAM> хм, интересно
[02:39:31] <ada_ru> (I_vlxy_I) хм. какой-то Ada.Text_IO.Write дофига сложный (я же правильно понимаю, что через мой Output_Stream всё выводиться будет в итоге через эту функцию?).

кажется нужно просто тупо какой-нибудь бинарь фигачить в файл.
[02:53:57] <ada_ru> (I_vlxy_I) А вот теперь я вообще нифига не понимаю.
[02:54:20] <ada_ru> (I_vlxy_I) уже напрямую зову fwrite:
  procedure PutF_Line(Item : String) is
     Siz : constant System.CRTL.size_t := Item'Length;
  begin
    if fwrite (Item'Address, 1, Siz, stdout) /= Siz then
        null;
     end if;
  end PutF_Line;
[02:54:27] <ada_ru> (I_vlxy_I) и нифига. в смысле - те же тормоза.
[02:55:12] <ada_ru> (I_vlxy_I) при этом в плюсцах тормозов нет.
[03:00:56] <ada_ru> (I_vlxy_I) тормоза заключаются именно в лавине системных вызовов. sys аж 10 секунд.
[03:01:06] <ada_ru> (I_vlxy_I) у плюсцов - секунды 1.5
[03:24:32] <ada_ru> (I_vlxy_I) strace показывает вот такое безобразие для Ады:
write(1, "The7NnJPyNRN7emvT3ZzSLissvqxPV3m"..., 113) = 113
write(1, "EbOlCCanghEJ0c25U6i9cpmNH3UyC Mg"..., 81) = 81  
write(1, "0n8oMRL4 c3pYimKYSunwoh0 4GvfrWy"..., 75) = 75  
write(1, "UAY1WhUHjWwE7BV9ugP3qhqidWqM4Nmj"..., 69) = 69  
write(1, "70ySiHvC cQG Aenbl", 18)      = 18              
write(1, "3aPs0tG5f1TQl4ZRRFHHpKLgeQ", 26) = 26           
write(1, "oXRVcgEimY9cM0TDwW4vLLAb6ASsY5je"..., 53) = 53  
write(1, "ctyAdhRCIFUGpBFMzcJxf20vEIcnTKu8"..., 191) = 191
[03:24:57] <ada_ru> (I_vlxy_I) в то время как для плюсов, вот такое:
write(1, "zx6oMgE684oRfjojoIwg4ftqrgYciCQ9"..., 4096) = 4096  
write(1, "WcLvDLRWN3iS7gC0gLmeCylPCR ri6Zw"..., 4096) = 4096  
write(1, "KcuO2Un 720qSGvO\nzzyGEt1zd0dJo5T"..., 4096) = 4096
write(1, "FMTRcpXC9ibyL4Bc2g E8eHRgdZsosLu"..., 4096) = 4096  
write(1, "T 3PssrLxItTlW8YZGQmiMa8w49nf2wJ"..., 4096) = 4096
[03:25:01] <ada_ru> (I_vlxy_I) почувствуйте разницу
[04:25:01] <ada_ru> (I_vlxy_I) А если перед циклом вывода сделать:
  res := Interfaces.C_Streams.setvbuf ( stdout,
                                        System.Null_Address ,
                                        Interfaces.C_Streams.IOFBF,
                                        4096 );
То оно начинает работать в два раза МЕДЛЕННЕЕ.
[04:33:46] <ada_ru> (I_vlxy_I) да, буферизация для stdout в Аде по умолчанию отключена. я только не понимаю почему я её включить никак не могу
[11:34:21] <ada_ru> (nitrocerber) Ацкий рантайм до сих пор не умеет на вендузе пути длиннее 256 символов, чего ты от него хочешь)
[11:34:31] <ada_ru> (nitrocerber) Надо тебе купить подписку)
[11:34:47] <ada_ru> (nitrocerber) И начат пылесочитт всеми этими вопросами мозги компиляторщикам
[11:40:08] <OCTAGRAM> надо купить подписку на I_vlxy_I, чтоб он сам себе мозги пылесосил (хорошо получается) и результаты коммитил в FSF GCC
[11:51:27] <ada_ru> (I_vlxy_I)  отвечает (nitrocerber) на <И начат пылесочитт в…>
Дык это не компилятор, это стандартна либа. По крайней мере мне так кажется.

Но конечно тут такие чудеса происходят, что у меня уже сомнения появляются :-)
[11:55:02] <ada_ru> (Максим) > в два раза МЕДЛЕННЕЕ
А strace что теперь говорит?
[12:01:53] <ada_ru> (I_vlxy_I)  отвечает (Максим) на <> в два раза МЕДЛЕНН…>
О, там интересно! Щща
[12:04:24] <ada_ru> (I_vlxy_I) write(1, "vo9vupiF3NXCRT8GrM9pkeMyQOCfECew"..., 66) = 66    
write(1, "6", 1)                        = 1                 
write(1, "KX0FsbvOicLRZISTelkEDlGbYo FTLsc"..., 201) = 201  
write(1, "d", 1)                        = 1                 
write(1, "7aMTEl5FICqpk93KI3W2rWV9IVI8JN w"..., 51) = 51    
write(1, "x", 1)                        = 1                 
write(1, "UEDDU2utdALObPI7i4g25h8HCc0wQXqJ"..., 355) = 355  
write(1, "J", 1)                        = 1                 
write(1, "ypY7EQDwwi4 RQEVOBjp0 z3Uo93QIpS"..., 76) = 76    
write(1, "c", 1)                        = 1                 
write(1, "qgIX2K6IR0si5g32IoMK3aCBPBWVAziK"..., 81) = 81    
write(1, "g", 1)                        = 1                 
write(1, "XgFx H", 6)                   = 6                 
write(1, "c", 1)                        = 1                 
write(1, "4ZxhzV", 6)                   = 6                 
write(1, "i", 1)                        = 1                 
write(1, "xnnAafasbgwK4pVfWBwXOYPpK2ItjCAJ"..., 44) = 44    
write(1, "O", 1)                        = 1                 
write(1, "KmEfmkkKoXF9KSTo7vXxqwpSSJeqMNzd"..., 173) = 173
[12:04:36] <ada_ru> (I_vlxy_I) То есть каждый второй вызов write теперь по ровно одному символу
[12:05:27] <ada_ru> (I_vlxy_I) то есть это не какой-то левый символ, это реально следующий символ который надо вывести. то есть выводит по итогу оно всё правильно.
[12:05:38] <ada_ru> (I_vlxy_I) данные не бьются
[12:05:58] <ada_ru> (I_vlxy_I) но в итоге сисколов становится в два раза больше
[12:06:01] <ada_ru> (I_vlxy_I) ровно в два раза
[13:17:53] <ada_ru> (I_vlxy_I) От этой Ады fwrite икает :-)
[13:27:58] <ada_ru> (Максим) Ага, такой fwrite значит
[13:28:29] <ada_ru> (I_vlxy_I) Всё же дизайн стандартной либы у современных ЯП мне в этом плане больше нравится, чем у плюсов и Ады.

В них libc если и используется, то только как прокси для самых базовых функций. А, например буферизация уже своя.

Причём делают это так: есть скажем просто интерфейс Writer (его реализуют например файлы). Он пишет as is, то есть в случае файла на каждый вызов Writer.write будет один сискол.

И есть отдельный BufWriter, который тоже реализует интерфейс Writer и который в качестве аргумента при его создании принимает другой Writer (пофиг какой). И он уже чисто буферизирует, подёргивая у низлежащего Writer’a функцию write по мере заполнения буфера.
[13:28:57] <ada_ru> (I_vlxy_I) Так оно сделано и в расте и в Го, и, если не путаю, даже в жабе.
[13:29:48] <ada_ru> (I_vlxy_I) Это гибко и удобно. И без накладных расходов, ибо тут достаточно статического полиморфизма.
[13:30:37] <ada_ru> (I_vlxy_I) И без виртуальных функций, если текущий язык это позволяет (плюсы и раст - позволяют точно).
[13:30:55] <ada_ru> (I_vlxy_I) А fwrite не нужен.
[13:48:17] <ada_ru> (nitrocerber) Мне тут сказали, что пул_лайн не нужен. вообще
[13:48:29] <ada_ru> (nitrocerber) только для соответствия стандарту)
[13:58:55] <ada_ru> (I_vlxy_I) Чаво?
[13:59:02] <ada_ru> (I_vlxy_I) А что нужно?
[14:02:38] <ada_ru> (nitrocerber) ¯\_(ツ)_/¯
[14:44:14] <ada_ru> (I_vlxy_I) fwrite? :-)
[18:16:44] <ada_ru> (insert_reference_here)  отвечает (I_vlxy_I) на <компактно, удобно, п…>
Можно взглянуть?
[18:21:23] <ada_ru> (insert_reference_here)  отвечает (I_vlxy_I) на <Ооо! In_Place_Merge_…>
in_place merge sort должна быть медленная
[18:21:46] <ada_ru> (I_vlxy_I)  отвечает (insert_reference_here) на <in_place merge sort …>
В плюсах работает быстро.
[18:25:25] <ada_ru> (I_vlxy_I) Но, наверно, можно ещё быстрее.
[18:28:56] <ada_ru> (insert_reference_here)  отвечает (I_vlxy_I) на <@insert_reference_he…>
На ум ничего, кроме лока стандартного ввода и увеличения размеров буферов, не приходит. Ну и сортировку более для трок подходящую, но это уже обсуждали
[18:31:48] <ada_ru> (insert_reference_here)  отвечает (insert_reference_here) на <На ум ничего, кроме …>
То есть натурально, BufReader::new(stdin) заменить на BufReader::new(stdin.lock())
[18:32:59] <ada_ru> (insert_reference_here) Хотя стоп, StdinLock уже реализует BufRead
[20:07:48] <ada_ru> (insert_reference_here) @I_vlxy_I с какой локалью тестировал? А то строки в Rust в кодировке UTF-8, так что lines валидирует строки, поэтому и возвращает Result
[20:08:52] <ada_ru> (I_vlxy_I)  отвечает (insert_reference_here) на <@I_vlxy_I с какой ло…>
LC_ALL=C
[20:37:26] <ada_ru> (insert_reference_here)  отвечает (I_vlxy_I) на <LC_ALL=C>
Попробуй перепроверить с LC_ALL="en_US.utf8"
[20:37:40] <ada_ru> (I_vlxy_I) думаешь быстрее будет?
[20:38:03] <ada_ru> (I_vlxy_I) так то я могу и так и сяк запускать. LC_ALL=C юзаю просто потому, что тогда стандартный sort работает быстро
[20:38:25] <ada_ru> (I_vlxy_I) и потому, что растовая сортировка тогда тесты проходит 😊
[20:40:27] <ada_ru> (insert_reference_here)  отвечает (I_vlxy_I) на <думаешь быстрее буде…>
Наоборот, но сравнение будет честнее
[20:40:35] <ada_ru> (insert_reference_here) (по идее)
[20:40:57] <ada_ru> (I_vlxy_I) не. раст игнорирует и сравнивает побайтово. то есть я вначале так запускал и ответ у них отличался.
[20:41:12] <ada_ru> (I_vlxy_I) не имеет смысла сравнивать скорость работы если ответ не верен.
[20:52:13] <ada_ru> (insert_reference_here) @I_vlxy_I https://doc.rust-lang.org/stable/std/io/trait.BufRead.html#tymethod.fill_buf
Вот способ считать просто байты, без конвертации
[21:11:06] <ada_ru> (I_vlxy_I) ну, наверное нужно поемнять кот тогда 😉
[21:12:46] <ada_ru> (insert_reference_here)  отвечает (I_vlxy_I) на <ну, наверное нужно п…>
Скинь предыдущий вариант ещё раз, пожалуйста
[21:13:13] <ada_ru> (insert_reference_here) И какой там символ в качестве разделителя строк? \n, как обычно на unix-like?
[21:17:17] <ada_ru> (I_vlxy_I)  отвечает (insert_reference_here) на <И какой там символ в…>
да, оно
[21:18:32] <ada_ru> (I_vlxy_I)  отвечает (insert_reference_here) на <Скинь предыдущий вар…>
https://godbolt.org/z/mC13MJ
[21:27:20] <ada_ru> (insert_reference_here) Я правильно понимаю, что все программы сравнивают побайтово?
[21:29:11] <ada_ru> (I_vlxy_I) да
[21:29:24] <ada_ru> (insert_reference_here) 👌
[21:32:28] <ada_ru> (I_vlxy_I) народ, а есть идеи как ловить эту штуку с fwrite в Аде?
[21:33:38] <ada_ru> (insert_reference_here)  отвечает (I_vlxy_I) на <https://godbolt.org/…>
Для начала попробуй вот так:
https://godbolt.org/z/mEjAH9
[21:41:19] <ada_ru> (I_vlxy_I)  отвечает (insert_reference_here) на <Для начала попробуй …>
ok. до референсной машины доберусь часа через два.
[22:04:52] <ada_ru> (insert_reference_here)  отвечает (I_vlxy_I) на <ok. до референсной м…>
Ещё вот без UTF-8 валидации: https://godbolt.org/z/FfpvAR
Не факт, что будет заметно быстрее
[22:06:54] <ada_ru> (I_vlxy_I) Спасибо. попробую.