LINUX.ORG.RU

Говорили что Перл старый, ни на что не способный язык. Проверим?

 , , , ,


9

4

Говорили что Перл старый, ни на что не способный язык. Проверим?

Задачка:

Необходимо для каждой пары слов получить новое слово, так, чтобы окончание первого совпадало с началом второго, например, шлакоблок + окунь = шлакоблокунь. Это слово надо вывести в стандартный поток вывода.Если слова возможно соединить несколькими способами, надо выбрать тот, что обеспечивает максимальную общую часть, например папа + папаха = папаха (а не папапаха). Необходимо написать последнее условие.

Я просто взял практически первое попавшаяся задание.

На Перле программа заняла 5 строк не считая ввода-вывода. С вводом-выводом - 7 строк.

А как у вас? На ваших Супер-пупер языках?

Перемещено xaizek из general

Перемещено hobbit из talks



Последнее исправление: Pinkbyte (всего исправлений: 1)
Ответ на: комментарий от kompospec

Вы можете использовать стандартный механизм терминала юникс для ввода и вывода в файл, с любым из решений которое работает с stdin и stdout

demensdeum
()
Последнее исправление: demensdeum (всего исправлений: 1)
Ответ на: комментарий от kompospec

Как то мне кажется - что это вы. Не стану с вами общаться. И никому не советую. А то получите в Телегу такие же матерки

kompospec
() автор топика
Ответ на: комментарий от kompospec

Дописал:

#!/usr/bin/perl

open D, 'vxod.txt';
open V, '>vyxod.txt';

while (<D>) {
$v='';
($_,$r)=split/[+\s]+/;
for$k(split(//,$r)){
$v.=$k;
$v1=$v if/$v$/}
$r=~s/$v1//;

print V "$_$r\n";
}
kompospec
() автор топика
Ответ на: комментарий от kompospec
#!/usr/bin/perl

use Time::HiRes;

print "Content-type: text/html\n\n";

&verx('Скрипт для слияния 2 слов');

$t = Time::HiRes::time;


open D, 'vxod.txt';
open V, '>vyxod.txt';

while (<D>) {
$v='';
($_,$r)=split/[+\s]+/;
for$k(split(//,$r)){
$v.=$k;
$v1=$v if/$v$/}
$r=~s/$v1//;

print V "$_$r\n";
}

$t2 = Time::HiRes::time;


$t3 = $t2-$t;
      print "Время работы скрипта ";
      printf('%0.8f', $t3);
      print " сек <p>";
      #print "$t3 <br>".time();

close V;

open V, 'vyxod.txt';
while (<V>) {
  
  print;
  
  }



&niz();
kompospec
() автор топика
Ответ на: комментарий от demensdeum

Меня просто поражают люди которые говорят банальные вещи с очень умно-значимым видом.

Причина только одна - для постижения этих банальностей эти люди потратили очень много времени и усилий.

kompospec
() автор топика
Ответ на: комментарий от kompospec

Время работы скрипта

Основное время, которое измеряет этот скрипт, - это время чтения и записи на диск, а также время вывода в консоль. Измерено это время с огромной относительной погрешностью. Один раз будет 0,00027609 с, другой раз будет 0,00056708 с. То есть не важно на каком языке будем писать.

Можно было бы запустить преобразование текста миллион раз. Это дало бы лучшее представление о скорости. Но результаты будут получены на разных компьютерах. Как их предлагаете сравнивать?

Kogrom
()
Ответ на: комментарий от demensdeum

А чё всё я? Я уже доказал всем что Перл лучший и самый быстрый. Что мне ещё доказывать? Вы думаете по другому - тогда и доказывайте. Если честно - ковыряние в скоростях мне не интересно от слова вообще.

kompospec
() автор топика
Ответ на: комментарий от kompospec

Да, вывода на экран нет. Я print в файл неправильно понял. Но в любом случае, работа с файлом (жестким диском) вносит большую погрешность. Если её убрать, то ОС тем более будет каждый раз показывать разный результат.

Тогда про что мне тут говорили что Перл очень низкопроизводительный?

Про Перл говорили так, потому что он интерпретируемый и с динамической типизацией. Для этой задачи неважно какой язык брать. Тормоза появятся при сложной обработке большого объёма данных, типа обработке изображений или видео. Или текст взять на пару сотен мегабайт.

Kogrom
()
Ответ на: комментарий от Kogrom

Не нужно голых слов. Давайте код. Дело в том, что я спорю не первый раз. - Перл был лучше С++ Гдето была тема - там проводили сравнение

kompospec
() автор топика
Ответ на: комментарий от demensdeum

Там код на Перле неправильный - слишком читаемый. Надо простые числа с помощью регулярок вычислять - тогда будет быстрее, чем C++.

Kogrom
()
Ответ на: комментарий от dsxl

Мило. C-шный вариант из того коммента на моей машине даёт

$ gcc -O0 sieve.c -o sieve
$ time ./sieve 50100200
50100191 3006742

real	0m1.104s
user	0m0.678s
sys	0m0.053s
$ gcc -O3 sieve.c -o sieve
$ time ./sieve 50100200
50100191 3006742

real	0m0.892s
user	0m0.476s
sys	0m0.044s

Хаскельный аналог на той же машине:

$ ghc -O0 --make sieve
[1 of 1] Compiling Main             ( sieve.hs, sieve.o )
Linking sieve ...
iMac:~ MigMit$ time ./sieve 50100200
(50100191,3006742)

real	0m33.922s
user	0m33.385s
sys	0m0.276s
$ ghc -O3 --make sieve
[1 of 1] Compiling Main             ( sieve.hs, sieve.o ) [Optimisation flags changed]
Linking sieve ...
$ time ./sieve 50100200
(50100191,3006742)

real	0m1.334s
user	0m0.901s
sys	0m0.069s

С оптимизацией — вполне неплохо, надо заметить. Не ожидал.

Сам код:

module Main where
import Control.Monad
import Data.Array.IO
import Data.Foldable
import System.Environment
main =
    do [arg] <- getArgs
       let size = read arg
       primes <- newArray (2, size) True :: IO (IOUArray Int Bool)
       forM_ (takeWhile (\i -> i*i <= size) [2..]) $ \i -> do
         isPrime <- readArray primes i
         if not isPrime
           then return ()
           else forM_ [2*i, 3*i .. size] $ \j -> writeArray primes j False
       let check :: (Int, Int) -> Int -> IO (Int, Int)
           check (j, k) i = do
             isPrime <- readArray primes i
             return $ if isPrime then (i, k+1) else (j, k)
       jk <- foldM check (0, 0) [2..size]
       print jk

Miguel ★★★★★
()
Ответ на: комментарий от kompospec

Перл был лучше С++

Ну наговнокодить на любом ЯП можно.

anc ★★★★★
()
Ответ на: комментарий от ugoday

Перл правда существенно медленнее. Было дело для прода парсили сквидовые логи. После обьема S перл стал совсем не интересен.

anc ★★★★★
()
Ответ на: комментарий от anc

Как по мне, так все решения нужно рассматривать в комплексе. Так-то что скорость, что краткость в отрыве от задачи и остальных характеристик языка не показатели. В плане разбора логов вполне может быть, что лёгкость распараллеливания может оказаться важнее скорости в однопоточном варианте, например.

ugoday ★★★★★
()
Ответ на: комментарий от ugoday

В плане разбора логов вполне может быть, что лёгкость распараллеливания может оказаться важнее скорости в однопоточном варианте, например.

На всякий случай. В моем примере переписали на С и все стало просто замечательно. И старый и новый варианты работали в однопотоке.
ЗЫ Я не против перла, написал на нем и немало. Я только про то, что каждой задаче свой инструмент.

anc ★★★★★
()
Ответ на: комментарий от anc

Так и я не против перла. Он не так страшен, как им пугают и на перле можно писать читаемые программы точно так же, как и на любом другом языке.

Просто победа в специальной олимпиаде — очень так себе аргумент в пользу любого языка.

ugoday ★★★★★
()
Ответ на: комментарий от ugoday

Эдак мы дойдём до того, что Перл, хороший, годный язык, знать который обязан каждый уважающий себя программист?

Да?

kompospec
() автор топика
Ответ на: комментарий от ugoday

и на перле можно писать читаемые программы

Не смог удержаться. Но баксы иногда просто выбешивать начинают :)

Просто победа в специальной олимпиаде — очень так себе аргумент в пользу любого языка.

Люто плюсую!

anc ★★★★★
()
Ответ на: комментарий от kompospec

А вы, кто не знает Перла - обзывалки с недостаточным образованием.

kompospec
() автор топика
Ответ на: комментарий от kompospec

только не программист, а системный администратор (сколько статей и книг было написано «perl в помощь системному администратору»), и не сейчас, так как python затмит его по популярности. В конце концов, автоматизация рутины - это его ниша (Practical Extraction and Report Language («практический язык для извлечения данных и составления отчётов»)).

Silerus ★★★★
()
Последнее исправление: Silerus (всего исправлений: 1)
Ответ на: комментарий от kompospec

Поздравляю, вы победили в специальной олимпиаде, не забудьте позвонить маме и порадовать

demensdeum
()
Последнее исправление: demensdeum (всего исправлений: 1)
Ответ на: комментарий от kompospec

Перл хороший и годный, в опытных руках не хуже руби с питоном. Но репутация у него загублена и в будущее перла я не верю.

ugoday ★★★★★
()
Ответ на: комментарий от kompospec

Ок. Для того, чтобы разница в скорости была видна лучше, мы усложним эту задачу. Возьмём список русских существительных, например отсюда: https://github.com/Harrix/Russian-Nouns/releases/download/v2.0/russian_nouns_v2.0.zip На основе этого списка создадим новый, со всеми новыми сочетаниями, где перекрываются не менее 3 букв. Тут даже секундомером можно замерять. У меня на моем стареньком ноуте ушло несколько минут и сгенерировалось почти 40 Мбайт из одного. У Вас есть код на Перле и C++. Можете сравнить время. Так как здесь тоже работа со строками, то у Перла есть шанс.

Начало выходного файла для примера:

абажурность = абажур + ажурность
абажуравель = абажур + журавель
абажуравельник = абажур + журавельник
абажуравлёнок = абажур + журавлёнок
абажуравлик = абажур + журавлик
абажуравлиха = абажур + журавлиха
абажуравль = абажур + журавль
абажуравушка = абажур + журавушка
абажурение = абажур + журение
абажурка = абажур + журка
абажурнал = абажур + журнал
абажурналец = абажур + журналец
абажурнализм = абажур + журнализм
абажурналист = абажур + журналист
...

Привожу свой код:

def check_combine
    mref res:string
    cref s1:string s2:string
    *len2 @int @size s2
    *j @int 0
    for *ch in s1
        if j len2
            break
        if ch s2|j
            j + 1
        else
            j = 0
    if < j 6 # 3 russian letters
        res = ""
    else
        *s3 @string s2 @erase 0 j
        res = s1 + s3
    
def main
    *inFile @file @set_mode "r" @open "russian_nouns.txt"
    *outFile @file @set_mode "w" @open "out_file.txt"
    *sOut @string ""
    *lines @array|string 
    lines inFile @getlines
    *counter @int 0
    for *s1 in lines
        for *s2 in lines
            if s1 s2
                continue
            *res @string @check_combine s1 s2
            if res s1
                continue
            if res s2
                continue
            if != res ""
                sOut + res " = " s1 " + " s2 "\n"
                counter + 1
                *ret @int counter % 1000
                if ret 0
                    @print "."
                    outFile @write sOut
                    sOut @clear
    outFile @write sOut 
    
    inFile @close
    outFile @close 

Дополнительно я каждые 1000 сочетаний выводил точку и скидывал строку в файл. Это мне нужно было только для контроля работы программы. Можно убрать для ускорения работы.

Kogrom
()
Ответ на: комментарий от ugoday

Кстати для меня тайна почему так произошло, мне кажется в CPAN есть не меньше вещей чем в какой-нибудь npm. Кого не спрашивал - говорят что проблема в околонулевой читаемости.

demensdeum
()
Ответ на: комментарий от demensdeum

у меня были проблемы с cpan (документация не соответствовала действительности) - когда пытаешься сделать по примеру в документации, а оно падает с ошибкой и как то руку опускаются разбираться почему.

Silerus ★★★★
()
Ответ на: комментарий от demensdeum

я всегда рассматривал perl - именно как язык автоматизации рутины, и вот когда ты пытаешься что то быстренько автоматизировать, а тебе под дых - это уже как то не интересно становится. Сейчас если мне что то такое понадобиться, а bash не хватит (очень муторно будет делать на bash) - я наверно выберу python, хотя меня бесят эти отступы (уж не знаю почему)

Silerus ★★★★
()
Последнее исправление: Silerus (всего исправлений: 1)
Ответ на: комментарий от demensdeum
  1. Хакерская культура оказалась слишком притягательной.

  2. Корпорациям не нужны выпендрёжники «я запишу это на 3 символа короче», а нужны стабильно работающие, воспроизводимые решения.

Поэтому везде питон, го и ява. А всякие перлы, лиспы и форты ютятся в маргинальном загончике.

ugoday ★★★★★
()
Ответ на: комментарий от Kogrom

Тут ведь уже говорили - что основное время программы - это ввод и вывод. То есть в задании нужно сделать как можно меньше выводов.

Единственное что мне приходит в голову - найти максимальное вхождение одного слова в другое.

Вывод - одна строка. Вычислений - много. Берёмся? Сейчас вытащу этот текстовый файл.

kompospec
() автор топика
Ответ на: комментарий от kompospec

Выгрузите в RAM весь словарь и получите метрики, это можно сделать с помощью строковых потоков.

demensdeum
()
Ответ на: комментарий от kompospec

Я уже начал. Код никому не показываем. Но и не мухлюем. Сейчас в словаре всё по алфавиту - так оно и должно оставаться. Ищем максимальное вхождение одного слова в другое. Ок?

kompospec
() автор топика
Ответ на: комментарий от kompospec

Что за ковбойская дуэль у вас, запустите оба варианта на своей машине.

demensdeum
()
Ответ на: комментарий от Kogrom

Могу дать фору: если отсортировать по размеру и использовать потоки, то можно ускорить вычисление в разы. Но в «моём Супер-пупер языке» пока потоков нет, да и настраиваемую сортировку я пока не завёз. Не нужно было. Оставлю это плюсовикам, если они захотят соревноваться.

Kogrom
()
Ответ на: комментарий от demensdeum

я не про то - распараллеливание имеет ограничения: не всякую задачу можно так решать, и прикрутить это понимание к парсеру - это уже задача.

Silerus ★★★★
()
Ответ на: комментарий от demensdeum

https://metacpan.org/dist/KappaCUDA/view/KappaCUDA.pod

Если взять новейшую видеокарту от NVidia и использовать CUDA, то может Перл и обгонит. Но тут проблема будет даже не в том, что основную работу на себя возьмёт библиотека на си. Дело в другом.

Задача у нас одноразовая. Соответственно, скрипт на Питоне, работающий 10 минут, выиграет у кода на плюсах, который работает 5 минут, если на скрипт мы потратили 2 минуты, а на плюсовую программу - 20. То есть если мы переусложним код на Перле, то мы всё равно потеряем во времени, даже если сам код будет работать быстро.

Вот я взялся за задачу в 19:16, а результат выдал в 19:30. Какой язык позволит получить результат так быстро? Только простой компилируемый язык со статической типизацией. И тут не годятся оба: и Перл, и Плюсы. Возможно, Паскаль или Фортран лучше бы подошли. Возможно, Ним. Точно не подойдут Хаскель и Раст.

Kogrom
()
Ответ на: комментарий от demensdeum

Давай возьмём твою ссылку на тест с простыми числами: https://blog.famzah.net/2016/09/10/cpp-vs-python-vs-php-vs-java-vs-others-performance-benchmark-2016-q3/

  • Код на Python 3.7 занимает 861 Bytes.
  • Код на Perl - 770 Bytes. Но тут мы будем запинаться о доллары. Так что соизмеримо с Питоном.
  • Код на C++ - 1.74 KB. То есть он больше примерно в 2 раза.

Понятно, что статическая типизация даст прирост, но лучше, чтобы это было 10-50%, а не 100%. Понятно, что цифры взяты с потолка. Я как-то считал количество символов из аналогичного теста. У меня вышло так:

  • python 1419
  • nim 2241
  • d 2298
  • rust 2460
  • go 2660
  • java 2855
  • c 2944

Ну вот Nim и D - подходят.

Ну это всё теоретические рассуждения. Можешь сам замерить сколько у тебя уйдёт времени на поиск максимального пересечения в словаре.

Kogrom
()
Последнее исправление: Kogrom (всего исправлений: 1)
Ответ на: комментарий от Kogrom

Какой язык позволит получить результат так быстро?

По этой ссылке выходит что быстрее всех C++, по CPU Time. Но конечно никто не говорит о скорости написания приложений на данных языках, мне было бы интересно посмотреть подобное исследование.

demensdeum
()
Ответ на: комментарий от Miguel

Возможно. В данной теме что-то похожее на Haskell появилось только на 15-й странице. Код действительно краткий, но появился намного позже, чем примеры на Питоне, например. Скорее всего, потому хаскелистов мало, а не потому что долго подбирали удачную формулу.

Вообще, допускаю, что для работы со строками Haskell и OCaml подходят хорошо. Не просто так же на них столько трансляторов сделано.

Kogrom
()
Ответ на: комментарий от Psilocybe

Не совсем. По скорости - да, а по краткости - нет. В питоновском коде много комментариев и учёт версии. Если это убрать, то размер будет 588 байт. А у PHP - 709.

Kogrom
()
Ответ на: комментарий от Kogrom

В данной теме что-то похожее на Haskell появилось только на 15-й странице.

Брехня. На четвёртой: Говорили что Перл старый, ни на что не способный язык. Проверим? (комментарий)

На пятой появилась целая программа: Говорили что Перл старый, ни на что не способный язык. Проверим? (комментарий)

Miguel ★★★★★
()
Ответ на: комментарий от Miguel

Для всех:

#!/usr/bin/perl

use utf8;
use open qw(:std :utf8); 

$t = time();

$| = 1;
open D, 'russian_nouns.txt';

for(0..2000) {
  $vv=<D>;
  $vv =~ s/\s+$//;
  @d = (@d, $vv);
  }

close D;
@d2 = @d;


for $v (@d){
    ++$i; if (++$j>99){
    $t2 = time()-$t;
    print $i."прошло $t2 секунд. $sov1 $str\n"; $j=0;}

  for $v2 (@d2) {&resh1 ()}
  
M1:  
  }
  
  #print "$sov1 $str";
  

sub resh1 {  
    $r=''; $l='';
    for(split(//,$v2)){
      $r .= $_;
      if ($v =~ /$r$/) {$l=$r}  
      }
    #print "$v-$l-$v2\n" if length $l>4 and $v ne $l;
    
    if ($l and ($l ne $v2) and ($l ne $v)){
    $sov = length $l;
    if ($sov>$sov1){$sov1=$sov; $str="$l - $v-$v2"}
}
}


sub resh2 {
  
    if($v ne $v2) {
    $_ = "$v $v2";
    /([^ ]*?)([^ ]*) \2/;
    
    if ($2 and ($2 ne $v2) and ($2 ne $v)){
    $sov = length $2;
    if ($sov>$sov1){$sov1=$sov; $str="$2 - $_"}

}
  }
  
  
  }

sub resh {

  $str = $_;
  
  }

kompospec
() автор топика
Ответ на: комментарий от kompospec

результат работы - &resh1:

100прошло 10 секунд. 5 атель - авансодатель-ателье
200прошло 21 секунд. 5 атель - авансодатель-ателье
300прошло 31 секунд. 5 атель - авансодатель-ателье
400прошло 42 секунд. 5 атель - авансодатель-ателье
500прошло 52 секунд. 6 бактер - азотобактер-бактериолог
600прошло 63 секунд. 6 бактер - азотобактер-бактериолог
700прошло 73 секунд. 6 бактер - азотобактер-бактериолог
800прошло 83 секунд. 6 бактер - азотобактер-бактериолог
900прошло 94 секунд. 6 бактер - азотобактер-бактериолог
1000прошло 104 секунд. 6 бактер - азотобактер-бактериолог
1100прошло 115 секунд. 6 бактер - азотобактер-бактериолог
1200прошло 125 секунд. 6 бактер - азотобактер-бактериолог
1300прошло 136 секунд. 6 бактер - азотобактер-бактериолог
1400прошло 146 секунд. 6 бактер - азотобактер-бактериолог
1500прошло 156 секунд. 6 бактер - азотобактер-бактериолог
1600прошло 167 секунд. 6 бактер - азотобактер-бактериолог
1700прошло 177 секунд. 6 бактер - азотобактер-бактериолог
1800прошло 188 секунд. 6 бактер - азотобактер-бактериолог
1900прошло 198 секунд. 6 бактер - азотобактер-бактериолог
2000прошло 209 секунд. 6 бактер - азотобактер-бактериолог


------------------
(program exited with code: 0)
Press return to continue

Неприемлемо долго!

kompospec
() автор топика
Последнее исправление: kompospec (всего исправлений: 1)
Ответ на: комментарий от kompospec

&resh2

100прошло 1 секунд. 5 атель - авансодатель ателье
200прошло 2 секунд. 5 атель - авансодатель ателье
300прошло 3 секунд. 5 атель - авансодатель ателье
400прошло 3 секунд. 5 атель - авансодатель ателье
500прошло 4 секунд. 6 бактер - азотобактер бактериолог
600прошло 5 секунд. 6 бактер - азотобактер бактериолог
700прошло 6 секунд. 6 бактер - азотобактер бактериолог
800прошло 7 секунд. 6 бактер - азотобактер бактериолог
900прошло 7 секунд. 6 бактер - азотобактер бактериолог
1000прошло 8 секунд. 6 бактер - азотобактер бактериолог
1100прошло 9 секунд. 6 бактер - азотобактер бактериолог
1200прошло 10 секунд. 6 бактер - азотобактер бактериолог
1300прошло 11 секунд. 6 бактер - азотобактер бактериолог
1400прошло 11 секунд. 6 бактер - азотобактер бактериолог
1500прошло 12 секунд. 6 бактер - азотобактер бактериолог
1600прошло 13 секунд. 6 бактер - азотобактер бактериолог
1700прошло 14 секунд. 6 бактер - азотобактер бактериолог
1800прошло 14 секунд. 6 бактер - азотобактер бактериолог
1900прошло 15 секунд. 6 бактер - азотобактер бактериолог
2000прошло 16 секунд. 6 бактер - азотобактер бактериолог


------------------
(program exited with code: 0)
Press return to continue

Это лучше, но тоже очень долго

kompospec
() автор топика
Последнее исправление: kompospec (всего исправлений: 1)
Ответ на: комментарий от kompospec

Оформил процесс перебора по предложенному образцу:

417      прошло: 0 секунд, длина: 4, ажур - абажур-ажурность
878657   прошло: 1 секунд, длина: 5, генез - абиогенез-генезис
4009466  прошло: 2 секунд, длина: 6, датель - авансодатель-дательница
4061251  прошло: 2 секунд, длина: 9, держатель - авансодержатель-держательница
4093816  прошло: 2 секунд, длина: 11, содержатель - авансодержатель-содержательн
ость
265157673 прошло: 25 секунд, длина: 13, производитель - воспроизводитель-
производительность

Результат: 13, производитель - воспроизводитель-производительность
Полное время переборов: 144 секунд

Первая цифра - счётчик переборов. Я использую DSL (предметно ориентированный язык), который транслируется в C++. Так что скорость примерно как у плюсов.

Kogrom
()
Ответ на: комментарий от kompospec

Да, весь словарь, но если одно из слов было меньше по длине, чем уже найденное максимальное перекрытие, то такую комбинацию пропускал, конечно. А, что, найдено перекрытие больше по длине?

Kogrom
()
Ответ на: комментарий от kompospec

Постарался вникнуть в несколько решений, которые не на регулярках. Они все одинаковые:

  1. Находим минимальное (Мин) из 2 слов и колМин;
  2. Цикл по колМин;
  3. Отрываем одну букву сзади Мин и сравниваем с концом 2 слова;
  4. Совпадение - Бинго!

А там есть в корне другие решения?

kompospec
() автор топика
Ответ на: комментарий от kompospec

Не могли бы вы прогнать мою программу на своём компьютере?

Я лучше сделаю по другому. Подправлю транслированный текст, чтобы не надо было типы и библиотеки DSL-а использовать, и выложу сюда.

#include <iostream>
#include <fstream>
#include <ctime>
#include <string>
#include <vector>
using namespace std;

void check_combine(string &res, size_t &len, const string &s1, const string &s2)
{
    len = 0;
    for(auto &ch: s1)
    {
        if(len == s2.size())
        {
            break;
        }
        if(ch == s2.at(len))
        {
            len += 1;
        }
        else
        {
            len = 0;
        }
    }
    if(!len)
    {
        res = "";
    }
    else
    {
        string s3  {s2};
        s3.erase(0, len);
        res = s1;
        res += s3;
    }
}

void getlines(vector<string> &lines, fstream & f)
{
    string str;
    while(getline(f, str))
    {
        lines.push_back(str);
    }
}

int main()
{
    fstream inFile;
    inFile.open ("russian_nouns.txt", std::fstream::in);
    vector<string> lines;
    getlines(lines, inFile);
    size_t maxLen  {0};
    size_t rusMaxLen  {0};
    string maxRes  {""};
    time_t startTime = time(nullptr);
    size_t counter  {0};
    for(auto &s1: lines)
    {
        for(auto &s2: lines)
        {
            counter += 1;
            if(s1 == s2)
            {
                continue;
            }
            if(s1.size() < maxLen)
            {
                continue;
            }
            if(s2.size() < maxLen)
            {
                continue;
            }
            size_t len  {0};
            string res;
            check_combine(res, len, s1, s2);
            if(res == s1)
            {
                continue;
            }
            if(res == s2)
            {
                continue;
            }
            if(len > maxLen)
            {
                maxLen = len;
                rusMaxLen = maxLen / 2;
                time_t delta = time(nullptr) - startTime;
                string deltaStr  {s2};
                deltaStr.erase(len);
                maxRes = deltaStr + " - " + s1 + '-' + s2;
                cout << counter << "\t прошло: " << delta << " секунд, длина: ";
                cout << rusMaxLen << ", " << maxRes << '\n';
            }
        }
    }
    cout << "\n\nРезультат: " << rusMaxLen << ", " << maxRes << '\n';
    time_t delta = time(nullptr) - startTime;
    cout << "Полное время переборов: " << delta;
    inFile.close();
    return 0;
}

Код немного странный, потому что из автоматически сгенерированного сделан. Но вроде рабочий. Этот у меня всё перебрал за 120 секунд. Можете проверить у себя.

Kogrom
()
Ответ на: комментарий от demensdeum

А вы? я С++ практически не пользуюсь чтоб понимать скинет он данные все сразу или выдаст частями в ходе выполнения. Факт в одном. Я запустил ту прогу. Попил чайку - Ни одной строки не появилось. Выключил прогу.

kompospec
() автор топика
Ответ на: комментарий от demensdeum

А у вас какое образование? Я просто не понимаю уровень на котором мне нужно объяснять? Про жадность вы точно ничего не знаете. А де ве по де те?

kompospec
() автор топика
Ответ на: комментарий от demensdeum

Ого! Де ве по де те - это школа. Правда математическая. Друган у меня был на дневном отделении КуАИ - он говорил что они это в школе ещё проходили.

kompospec
() автор топика
Последнее исправление: kompospec (всего исправлений: 1)
Ответ на: комментарий от kompospec

А тем временем с О3
2631741301 прошло: 86 секунд, длина: 1, а - ящурка-абажур
2631754737 прошло: 86 секунд, длина: 2, ка - ящурка-кабак
2631791506 прошло: 86 секунд, длина: 5, щурка - ящурка-щурка

demensdeum
()
Последнее исправление: demensdeum (всего исправлений: 1)
Ответ на: комментарий от kompospec

Linux demensdeum-HP-Pavilion-Notebook 5.4.0-89-generic #100-Ubuntu SMP Fri Sep 24 14:50:10 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

demensdeum
()
Ответ на: комментарий от demensdeum
#!/usr/bin/perl

use utf8;
use open qw(:std :utf8); 

$t = time();

$| = 1;
open D, 'russian_nouns.txt';

for(0..2000) {
  $vv=<D>;
  $vv =~ s/\s+$//;
  @d = (@d, $vv);
  }

close D;
@d2 = @d;


for $v (@d){
    ++$i; if (++$j>99){
    $t2 = time()-$t;
    print $i."прошло $t2 секунд. $sov1 $str\n"; $j=0;}

  for $v2 (@d2) {&resh1 ()}
  
M1:  
  }
  
  #print "$sov1 $str";
  

sub resh1 {  
    $r=''; $l='';
    for(split(//,$v2)){
      $r .= $_;
      if ($v =~ /$r$/) {$l=$r}  
      }
    #print "$v-$l-$v2\n" if length $l>4 and $v ne $l;
    
    if ($l and ($l ne $v2) and ($l ne $v)){
    $sov = length $l;
    if ($sov>$sov1){$sov1=$sov; $str="$l - $v-$v2"}
}
}


sub resh2 {
  
    if($v ne $v2) {
    $_ = "$v $v2";
    /([^ ]*?)([^ ]*) \2/;
    
    if ($2 and ($2 ne $v2) and ($2 ne $v)){
    $sov = length $2;
    if ($sov>$sov1){$sov1=$sov; $str="$2 - $_"}

}
  }
  
  
  }

sub resh {

  $str = $_;
  
  }

kompospec
() автор топика
Ответ на: комментарий от kompospec

Там 2 решения. Вам помочь прочитать код? Спрашивайте, если что непонятно

kompospec
() автор топика
Ответ на: комментарий от kompospec

perl -v This is perl 5, version 30, subversion 0 (v5.30.0) built for x86_64-linux-gnu-thread-multi

ок момент

demensdeum
()
Ответ на: комментарий от kompospec
perl test.perl 
100прошло 5 секунд. 5 атель - авансодатель-ателье
200прошло 9 секунд. 5 атель - авансодатель-ателье
300прошло 13 секунд. 5 атель - авансодатель-ателье
400прошло 17 секунд. 5 атель - авансодатель-ателье
500прошло 21 секунд. 6 бактер - азотобактер-бактериолог
600прошло 25 секунд. 6 бактер - азотобактер-бактериолог
700прошло 29 секунд. 6 бактер - азотобактер-бактериолог
800прошло 33 секунд. 6 бактер - азотобактер-бактериолог
900прошло 37 секунд. 6 бактер - азотобактер-бактериолог
1000прошло 41 секунд. 6 бактер - азотобактер-бактериолог
1100прошло 45 секунд. 6 бактер - азотобактер-бактериолог
1200прошло 49 секунд. 6 бактер - азотобактер-бактериолог
1300прошло 53 секунд. 6 бактер - азотобактер-бактериолог
1400прошло 57 секунд. 6 бактер - азотобактер-бактериолог
1500прошло 61 секунд. 6 бактер - азотобактер-бактериолог
1600прошло 65 секунд. 6 бактер - азотобактер-бактериолог
1700прошло 69 секунд. 6 бактер - азотобактер-бактериолог
1800прошло 74 секунд. 6 бактер - азотобактер-бактериолог
1900прошло 78 секунд. 6 бактер - азотобактер-бактериолог
2000прошло 82 секунд. 6 бактер - азотобактер-бактериолог
demensdeum
()
Ответ на: комментарий от kompospec

Ок, опубликуйте пожалуйста код без лишних вызовов, интерпретатору Perl будет проще

demensdeum
()
Ответ на: комментарий от demensdeum
#!/usr/bin/perl

use utf8;
use open qw(:std :utf8); 

$t = time();

$| = 1;
open D, 'russian_nouns.txt';

for(0..2000) {
  $vv=<D>;
  $vv =~ s/\s+$//;
  @d = (@d, $vv);
  }

close D;
@d2 = @d;


for $v (@d){
    ++$i; if (++$j>99){
    $t2 = time()-$t;
    print $i."прошло $t2 секунд. $sov1 $str\n"; $j=0;}

  for $v2 (@d2) {&resh2 ()}
  
M1:  
  }
  
  #print "$sov1 $str";
  

sub resh1 {  
    $r=''; $l='';
    for(split(//,$v2)){
      $r .= $_;
      if ($v =~ /$r$/) {$l=$r}  
      }
    #print "$v-$l-$v2\n" if length $l>4 and $v ne $l;
    
    if ($l and ($l ne $v2) and ($l ne $v)){
    $sov = length $l;
    if ($sov>$sov1){$sov1=$sov; $str="$l - $v-$v2"}
}
}


sub resh2 {
  
    if($v ne $v2) {
    $_ = "$v $v2";
    /([^ ]*?)([^ ]*) \2/;
    
    if ($2 and ($2 ne $v2) and ($2 ne $v)){
    $sov = length $2;
    if ($sov>$sov1){$sov1=$sov; $str="$2 - $_"}

}
  }
  
  
  }

sub resh {

  $str = $_;
  
  }

kompospec
() автор топика
Ответ на: комментарий от kompospec
perl test2.perl 
100прошло 0 секунд. 5 атель - авансодатель ателье
200прошло 1 секунд. 5 атель - авансодатель ателье
300прошло 1 секунд. 5 атель - авансодатель ателье
400прошло 2 секунд. 5 атель - авансодатель ателье
500прошло 2 секунд. 6 бактер - азотобактер бактериолог
600прошло 3 секунд. 6 бактер - азотобактер бактериолог
700прошло 3 секунд. 6 бактер - азотобактер бактериолог
800прошло 3 секунд. 6 бактер - азотобактер бактериолог
900прошло 4 секунд. 6 бактер - азотобактер бактериолог
1000прошло 4 секунд. 6 бактер - азотобактер бактериолог
1100прошло 5 секунд. 6 бактер - азотобактер бактериолог
1200прошло 5 секунд. 6 бактер - азотобактер бактериолог
1300прошло 5 секунд. 6 бактер - азотобактер бактериолог
1400прошло 6 секунд. 6 бактер - азотобактер бактериолог
1500прошло 6 секунд. 6 бактер - азотобактер бактериолог
1600прошло 7 секунд. 6 бактер - азотобактер бактериолог
1700прошло 7 секунд. 6 бактер - азотобактер бактериолог
1800прошло 7 секунд. 6 бактер - азотобактер бактериолог
1900прошло 8 секунд. 6 бактер - азотобактер бактериолог
2000прошло 8 секунд. 6 бактер - азотобактер бактериолог
demensdeum
()
Ответ на: комментарий от demensdeum

??? То есть?

У меня нет пока решения на Перл без регулярок.

И почему у меня не запустился С++ ? Вообще не запустился.

kompospec
() автор топика
Ответ на: комментарий от kompospec

Пока вывод только один. Регулярки на Перл - для этого - долго.

kompospec
() автор топика
Последнее исправление: kompospec (всего исправлений: 1)
Ответ на: комментарий от kompospec

Хотел уточнить у вас, чем закончился эксперимент. У меня работают оба варианта, C++ запускаю так:

clang++ test.cpp -O3 -o optimizedO3 && ./optimizedO3
Perl так:
perl test2.perl
Тестовый стенд: https://support.hp.com/us-en/document/c06074117/

demensdeum
()
Последнее исправление: demensdeum (всего исправлений: 1)
Ответ на: комментарий от demensdeum

Пусть прога выдаёт чаще промежуточные результаты. Но что это нам даст - если у нас разные алгоритмы решения?

Алгоритмы решения должны быть одинаковыми.

kompospec
() автор топика
Ответ на: комментарий от demensdeum

Для Перла - запуск правильный. Но я запускаю прям в редакторе - в Geany

kompospec
() автор топика
Ответ на: комментарий от demensdeum

g++ -Wall -c «u.cpp» (в каталоге: /home//Рабочий стол/словарь)

g++ -Wall -o «u» «u.cpp» (в каталоге: /home//Рабочий стол/словарь)

Сборка прошла успешно.

Это выдаёт редактор при компиляции С++

kompospec
() автор топика
Ответ на: комментарий от kompospec

Сейчас скину с промежуточным выводом, но там не как у вас, можете исправить как вам нужно

demensdeum
()
Ответ на: комментарий от kompospec
#include <iostream>
#include <fstream>
#include <ctime>
#include <string>
#include <vector>
using namespace std;

void check_combine(string &res, size_t &len, const string &s1, const string &s2)
{
    len = 0;
    for(auto &ch: s1)
    {
        if(len == s2.size())
        {
            break;
        }
        if(ch == s2.at(len))
        {
            len += 1;
        }
        else
        {
            len = 0;
        }
    }
    if(!len)
    {
        res = "";
    }
    else
    {
        string s3  {s2};
        s3.erase(0, len);
        res = s1;
        res += s3;
    }
}

void getlines(vector<string> &lines, fstream & f)
{
    string str;
    while(getline(f, str))
    {
        lines.push_back(str);
    }
}

int main()
{
    fstream inFile;
    inFile.open ("russian_nouns.txt", std::fstream::in);
    vector<string> lines;
    getlines(lines, inFile);
    inFile.close();
    auto i = 0;
    size_t maxLen  {0};
    size_t rusMaxLen  {0};
    string maxRes  {""};
    time_t startTime = time(nullptr);
    size_t counter  {0};
    for(auto &s1: lines)
    {
        for(auto &s2: lines)
        {
            counter += 1;
            if(s1 == s2)
            {
                continue;
            }
            if(s1.size() < maxLen)
            {
                continue;
            }
            if(s2.size() < maxLen)
            {
                continue;
            }
            size_t len  {0};
            string res;
            if (i % 1000000 == 0) {
              time_t delta = time(nullptr) - startTime;
              cout << "s1 " << s1 << endl << "s2 "<< s2 << "\t прошло: " << delta << " секунд" << endl;
            }
            i++;
            check_combine(res, len, s1, s2);
            if(res == s1)
            {
                continue;
            }
            if(res == s2)
            {
                continue;
            }
            if(len > maxLen)
            {
                maxLen = len;
                rusMaxLen = maxLen / 2;
                time_t delta = time(nullptr) - startTime;
                string deltaStr  {s2};
                deltaStr.erase(len);
                maxRes = deltaStr + " - " + s1 + '-' + s2;
                cout << counter << "\t прошло: " << delta << " секунд, длина: ";
                cout << rusMaxLen << ", " << maxRes << '\n';
            }
        }
    }
    cout << "\n\nРезультат: " << rusMaxLen << ", " << maxRes << '\n';
    time_t delta = time(nullptr) - startTime;
    cout << "Полное время переборов: " << delta;
    return 0;
}

Используйте флаги оптимизации O2, O3. Например g++ -O2 u.cpp && ./a.out

demensdeum
()
Ответ на: комментарий от Kogrom

Вкачусь и я, что ли. Кресты, требуются системные вызовы open, stat и mmap. Подсчитывается длина слова в байтах / 2, а не в символах. Обычно русские буквы занимают 2 байта, отсюда деление на 2. В остальном решение полностью честное.


#include <cassert>
#include <unistd.h>
#include <iostream>
#include <string_view>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <vector>
#include <algorithm>

int main() {
    constexpr auto filename = "russian_nouns.txt";
    int file = open(filename, O_RDONLY);
    if (file < 0) {
        perror("open failed: %s");
        return EXIT_FAILURE;
    }
    struct stat statbuf;
    if (fstat(file, &statbuf)) {
        perror("fstat failed: %s");
        return EXIT_FAILURE;
    }
    auto ptr = mmap(NULL, statbuf.st_size, PROT_READ, MAP_PRIVATE, file, 0);
    if (ptr == MAP_FAILED) {
        perror("mmap failed: %s");
        return EXIT_FAILURE;
    }

    std::vector<const char*> newlines;
    newlines.reserve(1024 * 1024);
    {
        auto begin = reinterpret_cast<char*>(ptr);
        auto end = begin + statbuf.st_size;

        newlines.push_back(begin - 1);
        while (begin != end) {
            if (*begin == '\n') {
                newlines.push_back(begin);
            }
            ++begin;
            //begin = std::find(begin, end, '\n');
        }
        if (newlines.size() > 0 && *newlines.back() != '\n') {
            ++newlines.back();
        }
    }

    std::size_t max_common_len{ 0 };
    for (std::size_t i = 0; i + 1 < newlines.size(); ++i) {
        std::string _( newlines[i] + 1, newlines[i + 1] - newlines[i] - 1 );
        if (_.size() < max_common_len) {
            continue;
        }
        std::string_view a{ _ };
        for (std::size_t j = 0; j + 1 < newlines.size(); ++j) {
            std::string_view b( newlines[j] + 1, newlines[j + 1] - newlines[j] - 1 );
            if (newlines[i] == newlines[j] || b.size() < max_common_len) {
                continue;
            }
            auto max = std::min(a.size(), b.size());
            if (max <= max_common_len || a.ends_with(b) || b.starts_with(a)) {
                continue;
            }
            auto a_ = a;
            auto b_ = b;
            a_.remove_prefix(a.size() - max);
            b_.remove_suffix(b.size() - max);
            while (max > max_common_len) {
                if (a_.ends_with(b_)) {
                    max_common_len = max;
                    std::cout << (max / 2) << ' ' << a << " + " << b << " = " << a << b.substr(b_.size()) << '\n';
                    break;
                }
                b_.remove_suffix(1);
                --max;
            }
        }
    }
}

$ clang++ golf.cxx -std=c++2a -march=native -Wall -Wextra -Ofast
$ time ./a.out 
4 абажур + ажурность = абажурность
5 абиогенез + генезис = абиогенезис
6 авансодатель + дательница = авансодательница
9 авансодержатель + держательница = авансодержательница
11 авансодержатель + содержательность = авансодержательность
13 воспроизводитель + производительность = воспроизводительность

real	0m5.169s
user	0m5.101s
sys	0m0.026s

Твой код компилировал с такими же флагами, получаю такой выхлоп:

$ clang++ -Ofast -march=native -std=c++2a kogrom.cxx
$ time ./a.out 
417	прошло: 0 секунд, длина: 4, ажур - абажур-ажурность
878657	прошло: 0 секунд, длина: 5, генез - абиогенез-генезис
4009466	прошло: 1 секунд, длина: 6, датель - авансодатель-дательница
4061251	прошло: 1 секунд, длина: 9, держатель - авансодержатель-держательница
4093816	прошло: 1 секунд, длина: 11, содержатель - авансодержатель-содержательность
265157673	прошло: 5 секунд, длина: 13, производитель - воспроизводитель-производительность


Результат: 13, производитель - воспроизводитель-производительность
Полное время переборов: 29
real	0m28.378s
user	0m27.626s
sys	0m0.149s
Siborgium ★★★★★
()
Последнее исправление: Siborgium (всего исправлений: 1)
Ответ на: комментарий от kompospec

Все и так знают что у Страуструпа толще, т.к. пока перлисты играли в код гольф, крестовики сидели и писали оптимизации компиляторов.

demensdeum
()
Ответ на: комментарий от demensdeum

Когда Перлисты, выполнив задание, уже трахали баб на Канарах, Крестовики всё продолжали спорить о том, какую типизацию применить в данном задании. Это вроде как я даже у вас где то вычитал

kompospec
() автор топика
Последнее исправление: kompospec (всего исправлений: 1)
Ответ на: комментарий от demensdeum

Да я Аппалон. Спасибо. Из Греческого зала.

kompospec
() автор топика
Ответ на: комментарий от demensdeum

Но вот если бы вы запустили на Перл с большим количеством строк. Это здесь:

for(0..2000) {

Мне Было бы интересно. У меня тормоза начинаются (с 30000) с 30 тысяч

kompospec
() автор топика
Последнее исправление: kompospec (всего исправлений: 1)
Ответ на: комментарий от kompospec

Ок, а как это относится к вопросу о низкой производительности Perl для целевой задачи?

demensdeum
()
Ответ на: комментарий от kompospec

Да, проблема есть с компилятором g++ в Linux и функцией getline(). В файле словаря каждая строка заканчивается на \r\n. Это и ведёт к некорректному поведению. Если в geany выполнить в Документ->Установить Окончания строк->LF(Unix), то всё заработает.

Kogrom
()
Ответ на: комментарий от Kogrom

Странно у меня g++ и clang++ работают нормально, g++ медленее только на 10 сек. Не выводит у kompspec по той причине что, как мне известно, CPU у него старенький и не успевает сделать весь перебор.

demensdeum
()
Ответ на: комментарий от demensdeum

Можно немного подчистить и всё будет работать с исходным файлом словаря:

#include <iostream>
#include <fstream>
#include <ctime>
#include <string>
#include <vector>
using namespace std;

void check_combine(string &res, size_t &len, const string &s1, const string &s2)
{
    len = 0;
    for(auto &ch: s1)
    {
        if(len == s2.size())
        {
            break;
        }
        if(ch == s2.at(len))
        {
            len += 1;
        }
        else
        {
            len = 0;
        }
    }
    if(!len)
    {
        res = "";
    }
    else
    {
        string s3  {s2};
        s3.erase(0, len);
        res = s1;
        res += s3;
    }
}

void getlines(vector<string> &lines, fstream & f)
{
    string str;
    while(getline(f, str))
    {
        if(str.back() == '\n')
            str.pop_back();
        if(str.back() == '\r')
            str.pop_back();
        lines.push_back(str);
    }
}

int main()
{
    fstream inFile;
    inFile.open ("/home/serg/cpp/russian_nouns.txt", std::fstream::in);
    vector<string> lines;
    getlines(lines, inFile);
    size_t maxLen  {0};
    size_t rusMaxLen  {0};
    string maxRes  {""};
    time_t startTime = time(nullptr);
    size_t counter  {0};
    for(auto &s1: lines)
    {
        for(auto &s2: lines)
        {
            counter += 1;
            if(s1 == s2)
            {
                continue;
            }
            if(s1.size() < maxLen)
            {
                continue;
            }
            if(s2.size() < maxLen)
            {
                continue;
            }
            size_t len  {0};
            string res;
            check_combine(res, len, s1, s2);
            if(res == s1)
            {
                continue;
            }
            if(res == s2)
            {
                continue;
            }
            if(len > maxLen)
            {
                maxLen = len;
                rusMaxLen = maxLen / 2;
                time_t delta = time(nullptr) - startTime;
                string deltaStr  {s2};
                deltaStr.erase(len);
                maxRes = deltaStr + " - " + s1 + '-' + s2;
                cout << counter << "\t прошло: " << delta << " секунд, длина: ";
                cout << rusMaxLen << ", " << maxRes << '\n';
            }
        }
    }
    cout << "\n\nРезультат: " << rusMaxLen << ", " << maxRes << '\n';
    time_t delta = time(nullptr) - startTime;
    cout << "Полное время переборов: " << delta;
    inFile.close();
    return 0;
}

Kogrom
()
Ответ на: комментарий от Kogrom
"/home/serg/cpp/russian_nouns.txt"

бывает, поправил

#include <iostream>
#include <fstream>
#include <ctime>
#include <string>
#include <vector>
using namespace std;

void check_combine(string &res, size_t &len, const string &s1, const string &s2)
{
    len = 0;
    for(auto &ch: s1)
    {
        if(len == s2.size())
        {
            break;
        }
        if(ch == s2.at(len))
        {
            len += 1;
        }
        else
        {
            len = 0;
        }
    }
    if(!len)
    {
        res = "";
    }
    else
    {
        string s3  {s2};
        s3.erase(0, len);
        res = s1;
        res += s3;
    }
}

void getlines(vector<string> &lines, fstream & f)
{
    string str;
    while(getline(f, str))
    {
        if(str.back() == '\n')
            str.pop_back();
        if(str.back() == '\r')
            str.pop_back();
        lines.push_back(str);
    }
}

int main()
{
    fstream inFile;
    inFile.open ("russian_nouns.txt", std::fstream::in);
    vector<string> lines;
    getlines(lines, inFile);
    size_t maxLen  {0};
    size_t rusMaxLen  {0};
    string maxRes  {""};
    time_t startTime = time(nullptr);
    size_t counter  {0};
    for(auto &s1: lines)
    {
        for(auto &s2: lines)
        {
            counter += 1;
            if(s1 == s2)
            {
                continue;
            }
            if(s1.size() < maxLen)
            {
                continue;
            }
            if(s2.size() < maxLen)
            {
                continue;
            }
            size_t len  {0};
            string res;
            check_combine(res, len, s1, s2);
            if(res == s1)
            {
                continue;
            }
            if(res == s2)
            {
                continue;
            }
            if(len > maxLen)
            {
                maxLen = len;
                rusMaxLen = maxLen / 2;
                time_t delta = time(nullptr) - startTime;
                string deltaStr  {s2};
                deltaStr.erase(len);
                maxRes = deltaStr + " - " + s1 + '-' + s2;
                cout << counter << "\t прошло: " << delta << " секунд, длина: ";
                cout << rusMaxLen << ", " << maxRes << '\n';
            }
        }
    }
    cout << "\n\nРезультат: " << rusMaxLen << ", " << maxRes << '\n';
    time_t delta = time(nullptr) - startTime;
    cout << "Полное время переборов: " << delta;
    inFile.close();
    return 0;
}
Запускаем
clang++ test.cpp -Ofast -o Ofast && ./Ofast
417      прошло: 0 секунд, длина: 4, ажур - абажур-ажурность
878657   прошло: 0 секунд, длина: 5, генез - абиогенез-генезис
4009466  прошло: 0 секунд, длина: 6, датель - авансодатель-дательница
4061251  прошло: 0 секунд, длина: 9, держатель - авансодержатель-держательница
4093816  прошло: 0 секунд, длина: 11, содержатель - авансодержатель-содержательность
265157673        прошло: 1 секунд, длина: 13, производитель - воспроизводитель-производительность
Результат: 13, производитель - воспроизводитель-производительность
Полное время переборов: 10

demensdeum
()
Ответ на: комментарий от Siborgium

Да, круто. Как я понимаю, основной выигрыш за счёт использования методов string_view. Можно ещё ускорить, если newlines отсортировать по убыванию длины строк, а затем циклы прерывать по достижению строки, которая меньше найденного максимального пересечения. Но я не стал заморачиваться, да и вроде уговор был не менять порядок.

Обычно русские буквы занимают 2 байта, отсюда деление на 2

Только символ № занимает 3 байта, так что нормально.

Kogrom
()
Ответ на: комментарий от Silerus

Похоже clang++ унижен и уничтожен с помощью g++ и pgo, далее старый вариант кода

#include <iostream>
#include <fstream>
#include <ctime>
#include <string>
#include <vector>
using namespace std;

void check_combine(string &res, size_t &len, const string &s1, const string &s2)
{
    len = 0;
    for(auto &ch: s1)
    {
        if(len == s2.size())
        {
            break;
        }
        if(ch == s2.at(len))
        {
            len += 1;
        }
        else
        {
            len = 0;
        }
    }
    if(!len)
    {
        res = "";
    }
    else
    {
        string s3  {s2};
        s3.erase(0, len);
        res = s1;
        res += s3;
    }
}

void getlines(vector<string> &lines, fstream & f)
{
    string str;
    while(getline(f, str))
    {
        lines.push_back(str);
    }
}

int main()
{
    fstream inFile;
    inFile.open ("russian_nouns.txt", std::fstream::in);
    vector<string> lines;
    getlines(lines, inFile);
    inFile.close();
    auto i = 0;
    size_t maxLen  {0};
    size_t rusMaxLen  {0};
    string maxRes  {""};
    time_t startTime = time(nullptr);
    size_t counter  {0};
    for(auto &s1: lines)
    {
        for(auto &s2: lines)
        {
            counter += 1;
            if(s1 == s2)
            {
                continue;
            }
            if(s1.size() < maxLen)
            {
                continue;
            }
            if(s2.size() < maxLen)
            {
                continue;
            }
            size_t len  {0};
            string res;
            // if (i % 1000000 == 0) {
            //   time_t delta = time(nullptr) - startTime;
            //   cout << "s1 " << s1 << endl << "s2 "<< s2 << "\t прошло: " << delta << " секунд" << endl;
            // }
            // i++;
            check_combine(res, len, s1, s2);
            if(res == s1)
            {
                continue;
            }
            if(res == s2)
            {
                continue;
            }
            if(len > maxLen)
            {
                maxLen = len;
                rusMaxLen = maxLen / 2;
                time_t delta = time(nullptr) - startTime;
                string deltaStr  {s2};
                deltaStr.erase(len);
                maxRes = deltaStr + " - " + s1 + '-' + s2;
                cout << counter << "\t прошло: " << delta << " секунд, длина: ";
                cout << rusMaxLen << ", " << maxRes << '\n';
            }
        }
    }
    cout << "\n\nРезультат: " << rusMaxLen << ", " << maxRes << '\n';
    time_t delta = time(nullptr) - startTime;
    cout << "Полное время переборов: " << delta;
    return 0;
}

echo "---"
g++ test.cpp -Ofast -fprofile-generate="profile" -o pgo
echo "---"
./pgo
echo "---"
g++ test.cpp -Ofast -fprofile-use="profile" -o pgo
echo "---"
./pgo
echo "---"
clang++ test.cpp -Ofast -o OfastClang
echo "---"
./OfastClang
Запускаем
PGO G++ - полное время переборов: 67
Clang++ - полное время переборов: 84

demensdeum
()
Последнее исправление: demensdeum (всего исправлений: 2)
Ответ на: комментарий от demensdeum

Всем:

Я дописал подпрограмму для расчёта без регулярок - Время одинаковое что и с правильной регуляркой.

#!/usr/bin/perl

use utf8;
use open qw(:std :utf8); 

$t = time();

$| = 1;
open D, 'russian_nouns.txt';

for(0..3000) {
  $vv=<D>;
  $vv =~ s/\s+$//;
  @d = (@d, $vv);
  }

close D;
@d2 = @d;


for $v (@d){
    ++$ii; if (++$j>99){
    $t2 = time()-$t;
    print $ii." прошло $t2 секунд. $sov1 $str\n"; $j=0;}

  for $v2 (@d2) {&resh3 ()}
  
M1:  
  }
  
sub resh3 {
  
  $lv = length $v;
  $lv2 = length $v2;

  if($lv>$lv2) {
  
    for($i=$lv2; $i>1; $i--) {
      $c = substr ($v, -$i,);
      $c2 = substr ($v2, 0, $i);
      if (($c eq $c2) and ($c ne $v2) and ($c ne $v)){
          $sov = length $c;
          if ($sov>$sov1){$sov1=$sov; $str="$c = $v-$v2"}
          }
        
  
      }

  
  }
  else {
    
        for($i=$lv; $i>1; $i--) {
      $c = substr ($v2, -$i,);
      $c2 = substr ($v, 0, $i);
      if (($c eq $c2) and ($c ne $v2) and ($c ne $v)){
          $sov = length $c;
          if ($sov>$sov1){$sov1=$sov; $str="$c = $v-$v2"}
          }
        
  
      }
    
    
    
    }
  
  
}
  

sub resh1 {  
    $r=''; $l='';
    for(split(//,$v2)){
      $r .= $_;
      if ($v =~ /$r$/) {$l=$r}  
      }
    #print "$v-$l-$v2\n" if length $l>4 and $v ne $l;
    
    if ($l and ($l ne $v2) and ($l ne $v)){
    $sov = length $l;
    if ($sov>$sov1){$sov1=$sov; $str="$l - $v-$v2"}
}
}


sub resh2 {
  
    if($v ne $v2) {
    $_ = "$v $v2";
    /([^ ]*?)([^ ]*) \2/;
    
    if ($2 and ($2 ne $v2) and ($2 ne $v)){
    $sov = length $2;
    if ($sov>$sov1){$sov1=$sov; $str="$2 - $_"}

}
  }
  
  
  }


kompospec
() автор топика
Ответ на: комментарий от kompospec

Если я не ошибся в программе можно сделать выводы про Регулярки:

  1. Плохая регулярка может сильно замедлить программу;
  2. Хорошая регулярка - не замедлит программу, но и не ускорит;
  3. Если не умеешь писать регулярки - не пиши, где это критично по скорости;
  4. Простые регулярки испортить очень трудно, но возможно.
kompospec
() автор топика
Ответ на: комментарий от kompospec

Я рад что вы пришли к выводу что лучше переписать на С++

demensdeum
()
Ответ на: комментарий от demensdeum

Да. Конечно. Много раз. Пишешь одну строку вместо 100 на Плюсах Она работает минуту. Ну и что? А 100 строк на Плюсах писать дольше гораздо.

kompospec
() автор топика
Ответ на: комментарий от kompospec

Вы на правильному пути, надеюсь по итогу вы забросите ностальгию по полумертвым языкам.

Никтож мою прогу на Перл не хочет запускать.

Ее запустили дважды и получили цифры, не в пользу Перла, на типичной для Перла задаче.

Насчет доминирования скажу, что по итогу всех замеров получилось что Перл позволяет доминировать в области быстрого написания медленных программ.
Мне нужны были цифры, я их получил, можете дальше продолжать доминировать уже на С++.

demensdeum
()
Последнее исправление: demensdeum (всего исправлений: 1)
Ответ на: комментарий от demensdeum

Обработка огромных файлов - это ни есть типичная задача для Перл. Тем более для Вебпрограммиста к которым я себя отношу.

kompospec
() автор топика
Ответ на: комментарий от kompospec

Обработка огромных файлов - это ни есть типичная задача для Перл.

Ниразу.

anc ★★★★★
()
Ответ на: комментарий от kompospec

А программу на С++ я не смог запустить ниразу.

конпелировать не пробовали?

anc ★★★★★
()
Ответ на: комментарий от Kogrom

Программа не запускается на полном файле. Но ведь можно сделать из полного файла - часть. Почему мне никто вчера про это не подсказал?

kompospec
() автор топика
Ответ на: комментарий от kompospec

Есть! В исходном файле или в вашей проге, вероятно, что что-то с кодировкой нитак. Перезаписал этот файл и ваша программа заработала!

417	 прошло: 0 секунд, длина: 4, ажур - абажур-ажурность
878674	 прошло: 0 секунд, длина: 5, генез - абиогенез-генезис
4009544	 прошло: 2 секунд, длина: 6, датель - авансодатель-дательница
4061330	 прошло: 2 секунд, длина: 9, держатель - авансодержатель-держательница
4093895	 прошло: 2 секунд, длина: 11, содержатель - авансодержатель-содержательность
265162841	 прошло: 29 секунд, длина: 13, производитель - воспроизводитель-производительность


Результат: 13, производитель - воспроизводитель-производительность
Полное время переборов: 161

------------------
(program exited with code: 0)
Press return to continue




kompospec
() автор топика
Ответ на: комментарий от kompospec

раз это прога работает на моём компе - значит нужно написать аналогичную на Перл. И тогда, наконец то, мы сможем сравнить скорости.

kompospec
() автор топика
Ответ на: комментарий от kompospec

Ого!

$ ./a.out
417	 прошло: 0 секунд, длина: 4, ажур - абажур-ажурность
878674	 прошло: 0 секунд, длина: 5, генез - абиогенез-генезис
4009544	 прошло: 1 секунд, длина: 6, датель - авансодатель-дательница
4061330	 прошло: 1 секунд, длина: 9, держатель - авансодержатель-держательница
4093895	 прошло: 1 секунд, длина: 11, содержатель - авансодержатель-содержательность
265162841	 прошло: 3 секунд, длина: 13, производитель - воспроизводитель-производительность


Результат: 13, производитель - воспроизводитель-производительность

kompospec
() автор топика
Ответ на: комментарий от kompospec

А как Питон? Как он себя чувствует с этой задачей? Есть ли ещё ЯП которые смогут справиться с этой задачей?

kompospec
() автор топика
Ответ на: комментарий от kompospec

Потому что на С++ программируют только старенькие дедушки.

kompospec
() автор топика
Ответ на: комментарий от kompospec

Поздравляю! Вернусь к теме о суммарном времени написания и выполнения кода. Изначальный код на моём самодельном языке был такой:

import time

def check_combine
    mref res:string len:int
    cref s1:string s2:string
    *len2 @int @size s2
    len = 0
    for *ch in s1
        if len len2
            break
        if ch s2|len
            len + 1
        else
            len = 0
    ifnot len
        res = ""
    else
        *s3 @string s2 @erase 0 len
        res = s1 + s3
    
def main
    *inFile @file @set_mode "r" @open "russian_nouns.txt"
    *lines @array|string 
    lines inFile @getlines
    *maxLen @int 0
    *rusMaxLen @int 0
    *maxRes @string ""
    *startTime @int @time:time
    *counter @int 0
    for *s1 in lines
        for *s2 in lines
            counter + 1
            if s1 s2
                continue
            *len1 @int @size s1
            *len2 @int @size s2
            if < len1 maxLen
                continue
            if < len2 maxLen
                continue
            *len @int 0
            *res @string
            res len @check_combine s1 s2
            if res s1
                continue
            if res s2
                continue
            if > len maxLen
                maxLen = len
                rusMaxLen = maxLen / 2
                *delta @int @time:time - startTime
                *deltaStr @string s2 @erase len
                maxRes = deltaStr + " - " s1 "-" s2
                @print* counter "\t прошло: " delta " секунд, длина: " rusMaxLen ", " maxRes "\n"
    @print* "\n\nРезультат: " rusMaxLen ", " maxRes "\n" 
    *delta @int @time:time - startTime
    @print* "Полное время переборов: " delta
    inFile @close

По длине он 1673 символа против 2457 на C++. То есть примерно в 1,5 раза короче. При том, можно ещё сократить, если сделать простейший вывод типов в конструкторе, а также открыть доступ к длине строки через переменную (это будет плохо с точки зрения инкапсуляции, но для маленьких одноразовых программ такое оправдано).

Но это не потому что C++ плохой. Для больших многоразовых программ он лучше. Если команда работает - он лучше, хотя хуже, чем Java и C#. Для маленьких одноразовых программ лучше были Перл и Питон, если нет требований по времени. Но Перл теперь заменяют на Раку, а Питон переусложнили.

Kogrom
()
Ответ на: комментарий от kompospec

Я ведь пишу программу конвертации перла на разные языки:

Ты уже разобрался как запустить компилятор плюсов?

TDrive ★★★★★
()
Ответ на: комментарий от kompospec

Это рабочий код. Выполняется он примерно на 20 % дольше, чем C++, если не использовать оптимизацию. Вероятно, из-за классов-обёрток для строк и массивов(векторов).

Kogrom
()
Ответ на: комментарий от Kogrom

не. ну это отлично.

Питон, нормальный, современный язык. Я повторю - На Плюсах пишут только старенькие, лысенькие дедушки. На стареньких заводиках бывшего СССР

kompospec
() автор топика
Последнее исправление: kompospec (всего исправлений: 2)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.