LINUX.ORG.RU
Ответ на: комментарий от Eddy_Em

Тогда и у меня весь код — плюсы ☺

ты натрави на него g++ - он тебе расскажет, какие там плюсы

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

Это как написать весь алгоритм на асме, запихать в asm { } и утверждать что код сишный.

найди asm в стандарте С - и потом выражай свое драгоценное мнение

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

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

Это ж ученые... не нам, убогим, чета;-)

А на кой черт, интересно, там нужны vector,

это такой контейнер массива. Я бы взял list - было бы куда быстрее ИМНО.

string,

это строки, просто строки.

algorithm (WTF?)?

алгоритмы, оттуда взят reverse.

И разве sstream и fstream не должны быть в iostream?

нет.

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

Фанбоев pure C припекло

Однако совместимость с C - одна из важнейших плюшек C++, так что всё честно. А вот что меня действительно смущает, так это почему в C# коде используется парочка вызовов к фреймворку вместо собственно теста. Ведь фреймворк написан на C++, без какой-то хардкорной оптимизации. Получается, мы доказали, что код на C++, вызванный из сишарпа, быстрее говнокода на C++ от человека, использующего вектор и не знающего о std::vector<>::reserve(). C++ быстрее C++, а C++ быстрее их обоих. Как неожиданно.

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

более правильно чем в оригинальном коде для С++

Ты по ссылке ходил?

It is of course possible to use faster libraries, or to write your own, but the purpose of the test is just to compare the standard facilities of both languages.

14203 ms для C# - это тоже в пределах погрешности?

Это неправильное тестирование, на что я уже намекнул.

я поражаюсь...

Неважно, правильно ли ты пишешь, если ты пишешь не то, что нужно.

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

It is of course possible to use faster libraries, or to write your own, but the purpose of the test is just to compare the standard facilities of both languages.

я использовал __исключительно__ стандартные средства С++ без всяких сторонних библиотек

Это неправильное тестирование, на что я уже намекнул.

оно неправильное только потому, что С++ не такое тормозное, чтоб не уложиться в секунду? ну ок - ладно, не буду спорить

Неважно, правильно ли ты пишешь, если ты пишешь не то, что нужно.

а что нужно то? задача решена, но вот не так как нужно? нужно, чтоб С# был впереди? ну ладно - и тут не буду спорить

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

Ты по ссылке ходил?

особенно забавно, что ты защищешь вариант, где автор использовал нестандартные средства из WinAPI, из-за чего его код не соберется стандартным g++ на линуксе

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

я использовал __исключительно__ стандартные средства С++ без всяких сторонних библиотек

А потом еще попадаются те, кто говорит, что C++ - больше, чем кривая надстройка над С ☺

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

А потом еще попадаются те, кто говорит, что C++ - больше, чем кривая надстройка над С

название С++ как бы намекает

vaino
()

Варианты не эквивалентны (в C++ файл читается построчно, а в C# - сразу весь, одна операция ввода-вывода всегда быстрее тысячи). «Ученые» доказали только свою некомпетентность.

Deleted
()
Ответ на: Фанбоев pure C припекло от quiet_readonly

почему в C# коде используется парочка вызовов к фреймворку вместо собственно теста. Ведь фреймворк написан на C++, без какой-то хардкорной оптимизации.

Вероятно, вы не работали с C#.

Не поленился. Открыл Reflector. Посмотрел, что File.ReadAllLines в итоге вызывает:

private static string[] InternalReadAllLines(string path, Encoding encoding)
{
    List<string> list = new List<string>();
    using (StreamReader reader = new StreamReader(path, encoding))
    {
        string str;
        while ((str = reader.ReadLine()) != null)
        {
            list.Add(str);
        }
    }
    return list.ToArray();
}
dave ★★★★★
()
Ответ на: комментарий от dave

Ух ты, в кои-то веки C# действительно работает сам. Это не отменяет вопроса, почему автор использовал std::vector без reserve, если даже авторы точки предпочитают std::list?

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

я использовал __исключительно__ стандартные средства С++

Когда говорят о стандартных средствах C++ - имеют в виду STL. Это на уровне соглашений. Это, возможно, не всегда так, но в данном случае сам автор тестировал STL, так что твой тест неравносилен его тесту, и сравнивать их нельзя.

оно неправильное только потому, что С++ не такое тормозное

Потому, что ты, судя по всему, не учитываешь запуск и разогрев виртуальной машины, а он к «скорости языка» обычно не относится. Хотя его и автор не учитывает.

особенно забавно, что ты защищешь вариант

Я никакой вариант не защищаю. Я лишь замечаю, что вы тестировали разные вещи, поэтому и выводы разные.

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

Ух ты, в кои-то веки C# действительно работает сам. Это не отменяет вопроса, почему автор использовал std::vector без reserve, если даже авторы точки предпочитают std::list?

System.Collections.Generic.List<T> в .NET подобен std::vector из C++. Названия могут сбить с толку.

Вектор тут ни при чем. Как я уже писал. Каждый элемент копируется в среднем всего один раз при добавлении.

dave ★★★★★
()

iostreams - говно, это давно всем давно ясно. У этой библиотеки нет ни одного достоинства.

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

Когда говорят о стандартных средствах C++ - имеют в виду STL. Это на уровне соглашений

нет, имеют ввиду то, что есть в стандарте, и там далеко не только STL, кстати iostreams, string и пр. - не часть STL

Потому, что ты, судя по всему, не учитываешь запуск и разогрев виртуальной машины, а он к «скорости языка» обычно не относится. Хотя его и автор не учитывает.

совсем наоборот - для C# меряется только чистое время исполнения внутри алгоритма, для С++ - я замерял все время работы от запуска программы и до выхода из нее

вы тестировали разные вещи

я тестировал альтернативный вариант решения задачи на С++, человек по ссылке аппелировал именно к ЯП, а не способу решения

vaino
()

Это случаем не британские учёные выясняли? :D

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

для C# меряется только чистое время исполнения внутри алгоритма

Всё равно JIT, афаик, включён в это время. Для серьёзного тестирования нужна консультация спеца по Mono - я Mono не знаю, ты, думаю, тоже, и к тому же предвзят ;)

я тестировал альтернативный вариант решения задачи на С++

У человека решение работает на файле любого размера, а у тебя на достаточно большом сфейлится.

человек по ссылке аппелировал именно к ЯП, а не способу решения

Ну ты прочитай всё-таки текст - он же прямо пишет: «Я знаю, что можно сделать быстрее. Я специально использую наивную реализацию на iostream и STL, чтобы убедиться, что они тормоза». То есть говоря в заголовке «C++», автор имеет в виду STL, о чём я и толкую.

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

Всё равно JIT, афаик, включён в это время.

и не влияет существенно на время исполнения, при росте кол-ва итераций и данных - время растет пропорционально

и к тому же предвзят ;)

я не ставлю цели показать, что C# - медленный, только то, что человек по ссылке не умеет писать ни на С++, ни на C#

У человека решение работает на файле любого размера, а у тебя на достаточно большом сфейлится.

я сразу написал, что решение «грязное», там можно много чего добавить - например проверку на существование файла и т.д., есть даже очевидная мелкая недоработка, не влияющая на скорость, но целью не было написание полноценной программы, только показать скорость алгоритма

Ну ты прочитай всё-таки текст - он же прямо пишет: «Я знаю, что можно сделать быстрее. Я специально использую наивную реализацию на iostream и ST

у тебя хорошая фантазия :), он пишет не это, он пишет, что есть „faster libraries“, т.е. примитивный вариант вроде моего ему даже в голову не приходит, он привык использовать библиотеки, а не писать код самостоятельно

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

примитивный вариант вроде моего ему даже в голову не приходит, он привык использовать библиотеки, а не писать код самостоятельно

А зачем нужна _своя_ библиотека ввода-вывода?

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

А зачем нужна _своя_ библиотека ввода-вывода?

а где ты увидел свою _библиотеку ввода-вывода_?

vaino
()

Кто-нибудь, расскажите тому чуваку про sync_with_stdio(false), мне лень там регаться ради коммента.

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

я сразу написал, что решение «грязное»

Это не просто грязь, это принципиально - может, у него половина времени тратится на постоянную переаллокацию, а ReadAllLines, достаточно одной. Зато его решение корректно, а твоё - нет.

только показать скорость алгоритма

Ты показал скорость некорректного алгоритма.

примитивный вариант вроде моего ему даже в голову не приходит, он привык использовать библиотеки

Это ты упорно не хочешь понять, что он тестирует. Его целью было использовать библиотеки, а конкретно, в случае плюсов, iostream/STL.

C++'s standard streams are slower than you can imagine. Much, much slower than .NET's. ... By curiosity, I decided to write a simple benchmark and see for myself.

I'm aware that a faster C++ version is possible. The C++ version I wrote is pure STL and very straightforward.

В конце концов,

If an obvious, faster approach exists for C++, I'm all ears.

Отпишись прямо ему. Может, я просто объяснять не умею.

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

Ты показал скорость некорректного алгоритма

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

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

Это как написать весь алгоритм на асме, запихать в asm { } и утверждать что код сишный.

Это как написать весь алгоритм на асме, скомпилировать и запихать машинный код в массив, потом скастовать указатель на массив в указатель на функцию и вызвать эту функцию

FIX :)

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

Это ты упорно не хочешь понять, что он тестирует. Его целью было использовать библиотеки, а конкретно, в случае плюсов, iostream/STL.

if (vec.size() >= vec.capacity())
    vec.reserve(vec.size() * 2);

Это - STL. А то, что по ссылке - говнокод.

Предвидя возмущение типа «да тут целых 2 строки добавить надо!», уточню: std::list обойдётся и без этих двух строк, да и вообще такая шняга делается только в узких местах, а тестовый пример является как раз таким местом.

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

В моём STL push_back и так при необходимости удваивает объём памяти под данные.

unsigned ★★★★
()
...
var lines = File.ReadAllLines("text.txt");
...
...
 while(getline(inFile, line)) {
...

Ну очень честный тест, да.

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

Ничего, что они в приплюснутом варианте читают файл по строкам, а в шарповом режут на строки прочитанный целиком файл? Что быстрее, одна операция ввода-вывода или 100?

Опередили :)

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

В дотнетовском варианте читается поседовательно строка за строкой. Все строки запихиваются в вектор (в .NET это List<T>), который в конце преобразуется в массив строк. Выше я привел соответствующий код из рефлектора (это что-то типа дизассемблера для .NET с многочисленными плюшками типа просмотра документации).

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

код по ссылке работает аналогично моему, std::string - не работает с utf8

Это лишь доказывает, что в C++ (или в твой С) код надо добавить конвертацию в UTF16 и обратно, или как-то переворачивать UTF8 in place, для того, что-бы получить аналогичный C#-у код. Что еще замедлит C++ решение.

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

В дотнетовском варианте читается поседовательно строка за строкой. Все строки запихиваются в вектор (в .NET это List<T>), который в конце преобразуется в массив строк. Выше я привел соответствующий код из рефлектора (это что-то типа дизассемблера для .NET с многочисленными плюшками типа просмотра документации).

Да, я сейчас тоже проверил это в рефлекторе. Получается, то ввод-вывод в дотнэте быстрей нативного.

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

А если еще и это XobotOS — порт Android на C# принять во внимание то получается что dotnet быстрее процессора. И почему тогда его Microsoft закопала?

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

Наверное, запускать с моно не совсем честно, ведь оно тормознее оригинального дотнета.

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

надо добавить конвертацию в UTF16 и обратно, или как-то переворачивать UTF8 in place

#include <cstdio>
#include <cstdlib>
#include <cstring>

static const char u8len[ 256 ] =
{
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,  3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5
};

int main()
{
	char char_buf[ 8 ];
	char ch;
	char clen;
	char *utf8;
	char *line;
	int j;

	for( size_t k = 0 ; k < 20 ; ++k )
	{
		FILE *f = fopen( "text.txt", "rt+" );

		fseek( f, 0, SEEK_END );
		int count = ftell( f );
		fseek( f, 0, SEEK_SET );

		char *text_buf = (char*) malloc( count );
		char *line_buf = (char*) malloc( count );
		char *el = line_buf + count;

		line = el;

		fread( text_buf, 1, count, f );
		for( int i = 0 ; i < count ; ++i )
		{
			ch = text_buf[ i ];
			if( ch == '\n' )
			{
				int len = el - line;
				memcpy( text_buf + i - len, line, len );
				line = el;
			}
			else
			{
				clen = u8len[ (unsigned char) ch ];
				if( !clen )
				{
					*--line = ch;
				}
				else
				{
					++clen;
					utf8 = text_buf + i + clen;
					for( j = 0 ; j < clen ; ++j )
						*--line = *--utf8;

					i += clen - 1;
				}
			}
		}

		fseek( f, 0, SEEK_SET );
		fwrite( text_buf, 1, count, f );
		fclose( f );

		free( text_buf );
		free( line_buf );
	}
}

заодно сделал честную работу с памятью на каждой итерации, для файла на 265Мб из строк такого вида:

«Это лишь доказывает, что в C++ (или в твой С) код надо добавить конвертацию в UTF16 и обратно, или как-то переворачивать UTF8 in place, для того, что-бы получить аналогичный C#-у код. Что еще замедлит C++ решение.»

С++ отработал за 13273ms, C# за 272768 ms, притом для С++ есть очевидные оптимизации, но мне уже лень их прикручивать

vaino
()

Поправил C++ код так, чтобы он собирался:

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

static inline double diffclock(clock_t clock1,clock_t clock2)
{
  double diffticks=clock1-clock2;
  double diffms=(diffticks)/(CLOCKS_PER_SEC/1000);
  return diffms;
}

void CPPPerformOperation() {
  vector<string> lines;
  ifstream inFile("text.txt");
  string line;
  while(getline(inFile, line)) {
    lines.push_back(line);
  }
  for (size_t i = 0; i < lines.size(); ++i) {
    reverse(begin(lines[i]), end(lines[i]));
  }
  ofstream outFile("text.txt");
  for (auto it = begin(lines); it != end(lines); ++it) {
    outFile << *it << "\n";
  }
}

int main() {
  double totalTime = 0;
  clock_t start, end;

  // call once for warm-up...
  CPPPerformOperation();
  for (int i = 0; i < 20; ++i) {
    start = clock();
    CPPPerformOperation();
    end = clock();
    totalTime += diffclock(end, start);
  }
  cout << "CPP time : " << totalTime << " milliseconds\n";
}

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

$ g++ -std=c++0x -O0 test.cpp -o test.O0
$ g++ -std=c++0x -O2 test.cpp -o test.O2
$ gmcs test.cs
$ du -h text.txt 
1.8M	text.txt
$ ./test.exe 
C# time: 9670 ms
$ ./test.O0 
CPP time : 1740 milliseconds
$ ./test.O2
CPP time : 620 milliseconds

А если взять файл того же размера что и по ссылке, то

$ du -h text.txt 
172K	text.txt
$ ./test.exe 
C# time: 906 ms
$ ./test.O0  
CPP time : 150 milliseconds
$ ./test.O2
CPP time : 50 milliseconds
$ 

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

Если кому интересно, то обрабатываемый файл располагался на tmpfs, процессор Intel Core 2 Duo 4300 1.80GHz, память DDR2 533 MHz.

kim-roader ★★
()
Ответ на: комментарий от Eddy_Em

Интересно, что они будут делать, если файлик будет иметь размер в пару ГБ?

Хотя бы mmap сделали, что ли…

И чем тебе поможет mmap против 3+-гигабайтного файла на 32 битах?

И да, самостоятельное блочное чтение эффективнее mmap'а.

red_eyed_peguin
()
Ответ на: комментарий от kim-roader

Возможно проблемы в MS реализации плюсового рантайма. Или «ученый» использовал managed c++. Или ещё что-то подобное.

kim-roader ★★
()
Ответ на: комментарий от red_eyed_peguin

И чем тебе поможет mmap против 3+-гигабайтного файла на 32 битах?

Мне не придется париться с чтением по кускам: ядро само все сделает.

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

Мне не придется париться с чтением по кускам: ядро само все сделает.

Фу, ты настолько некомпетентен, что даже не знаешь о том, что в 32-битном пространстве в линксе невозможно отммапить 3-гигабайтный файл? Кстати, заодно можешь подумать над вопросом «что будет, если VIRT превысит 3GB в 32-битном приложении», а также походить по граблям переполнения адресного пространства в 64-битном приложении (да, такое бывает, лично сталкивался).

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

Да, я сейчас тоже проверил это в рефлекторе. Получается, то ввод-вывод в дотнэте быстрей нативного.

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

@all

Честно говоря, тесты самому запускать лень. Но могу сказать, что .NET довольно шустр. Работаю с ним почти десять лет. Неплохая штука. Жаль только, что непереносимая да и от микрософта.

Моно же гораздо медленнее - на нем сравнивать нельзя. Кстати, у моно, наверняка, другая реализация File и StreamReader. Главное, у моно другая и существенно более медленная реализация сборщика мусора, да много еще чего медленнее. Кстати, не знаю, как сейчас, но раньше они использовали известный сборщик, написанный на C++ и для C++. Названия уже не помню, но тормозил он конкретно. То ли дело в .NET - там сборщик мусора переписывали с самого лиспа ;)

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

не думаю. Всё-таки С и C++ - два разных языка, а вышеприведённый код практически полностью C-шный(ну, за исключением include)

И, мне кажется, что Страуструп бы не одобрил.

lazyklimm ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.