Managed vs Unmanaged code. Round 1. (не холивара для, а справедливости ради)

Nov 02, 2010 21:37

Флуд :)

Много лет идет непримиримая война между сторонниками и противниками .NET. В последнее время кодеры самостоятельными исследованиями занимаются крайне редко, а проверкой существующих гипотез и подавно. Кто-то верит в одну гипотезу, кто-то в другую, а кто-то видел как на форуме вязальщиц-мотористок один дядька сказал что все они глупые, потому что Язык Всех Языков - VisualBasic. При встрече на просторах Сети противоборствующие группировки объединяются по религиозным признакам и поливают друг-друга грязью до тех пор, пока злобный модератор не прикроет тред или не перебанит половину участников. Обычно, спор носит ЧистаСпортивный характер. Ну что-то вроде "А !!! Йес !!! Пацаны мы их уделали !!!". Да... холивар страшная штука :) Потрепаться-то конечно интересно, но когда доходит до дела, возникают вопросы: "Я вроди так же писал на Си, а на шарпе - тормозит дико ?", "Раньше мой любимый Toad загружался раньше чем я второй раз крысой по иконке нажму, а теперь я успеваю попить кофе, сбегать за пивом и стать отцом 3-х детей(и мужем троих самок из разных частей города). А в перерывах между зависаниями и вылетами я бьюсь головой об стенку. Почему ?".

Сначала я хочу воткнуть свои 5 копеек и попытаться со стороны (на самом деле я тоже в религиозной группировке, токо тс-с-с :) ) посмотреть на предмет, и задать вопросы не особо пытаясь разобраться в тонкостях программирования вообще.

  1. Откуда у .NET столько противников ? Нет, я понимаю что Мелкомягких не все готовы на руках носить, но все-же !
  2. Неужели все хотят изгадить перспективную технологию просто так ? Всему есть причина... может не все так безоблачно как рисует любимая и заботливая корпорация ?
  3. Грхм. Очень странный вопрос, но на него ответ я знаю: "Почему мне хочется нелюбить .NET (и собственно я нет-нет да иногда отстаиваю религиозные убеждения по этому поводу) ?
      Все очень просто
      1) у меня было немало именно .NET'овских приложений (сказать "все" не могу, вот с VisualStudio, например, все нормально) которые дико тормозили и вылетали, чем естественно вызывали негодование.
      2) Несколько попыток написания программ на C# оказались неудачными. Тут уж склоня голову вполне могу признать криворукость, но насколько мне казалось в момент написания... никакого особо "тяжкого" преступления я не совершал.
      3) Писями по воде виляно, но тот факт что процессор СиШарпов не знает означает что все-равно выполняется машинный код, а значит приложение может быть написано эффективнее, т.к. не нужно никакое постороннее вмешательство.


Ближе к телу.

Грхм... К чему это я...
  А ! Ну да ! Это безобразие нужно проверить ! Собцтвенно вооружившись банкой пива, чипсами и IDE начнем...
Значит сегодня, уж не помню во сколько здесь была найдена ссылка:http://blogs.msdn.com/b/ricom/archive/2005/05/10/416151.aspx. Коротко говоря меня удивила такая табличка:

Version Execution Time
(seconds) Unmanaged v1 1.328 Unmanaged v2 0.828 Unmanaged v3 0.343 Unmanaged v4 0.187 Unmanaged v5 With Bug 0.296 Unmanaged v5 Corrected 0.124 Unoptimized Managed port of v1    0.124 Optimized Managed port of v1 0.093 Unmanaged v6 0.062

Больше всего поразила разница между Unmanaged v1 и Unoptimized Managed port of v1. "Неужели он настолько лучше ?". Хм. Может быть я плохо смотрел, исходника Unmanaged v1 я не увидел, но такая разница в скорости повергла меня в шок. Целый день занимаясь делами думал "а не перейти-ли на С# под юзермодом ?". Хм. Все-таки решил проверить... Код оказался так-себе, и что меня всегда поражает когда смотришь на подобные тесты, так это то что он как обычно набит циклами. Есть у меня одно подозрение, что это сильно увеличивает скорость в C#, но его подтвердить/опровергнуть пока не могу.

В общем решил не перебирать, а переписать(точнее подогнать) это безобразие под C++ так, чтобы сделать минимум изменений (если самому заняться оптимизацией того что есть, то... ээээ... что с чем сравнивать ? Скилы кодеров ?)

Консольное приложение (С#)

Program.cs

using System; using System.IO; using System.Text; using System.Collections;   namespace KillThemAllManaged { class Program { [System.Runtime.InteropServices.DllImport("Kernel32.dll")] private static extern bool QueryPerformanceCounter(out long lpPerformanceCount); [System.Runtime.InteropServices.DllImport("Kernel32.dll")] private static extern bool QueryPerformanceFrequency(out long lpFrequency);   public static long StartTime, EndTime, Freq;   static void Main(string[] args) { QueryPerformanceFrequency(out Freq); QueryPerformanceCounter(out StartTime);   Dictionary dict = new Dictionary();   QueryPerformanceCounter(out EndTime);   Console.WriteLine("Length: {0}", dict.Length()); Console.WriteLine("Frequency: {0:n0}", Freq); Console.WriteLine("Time: {0:n5}s", (EndTime - StartTime)/(double)Freq); }   class DictionaryEntry { private string trad; private string pinyin; public string english;   static public DictionaryEntry ParseBuffer(char[] line, int ibIn, int ibMax, out int ibOut) { DictionaryEntry de = new DictionaryEntry();   int state = 0; char chTrans = ' '; int start = ibIn; int end = 0; int i;   for (i = ibIn; line[i] != '\n'; i++) { if (line[i] != chTrans) continue; switch (state) { case 0://Китайское грамото de.trad = new String(line, start, i - start); state = 1; chTrans = '['; break; case 1: start = i + 1; chTrans = ']'; state = 2; break; case 2: // Записать "транскрипцию" и искать перевод de.pinyin = new String(line, start, i - start); chTrans = '/'; state = 3; break; case 3: // Перевод собссна start = i + 1; state = 4; break; case 4: end = i; state = 5; break; case 5: // Где заканчивается перевод... end = i; break; } } ibOut = i;   if (state == 5) { de.english = new String(line, start, end - start); return de; } return null; } }   class Dictionary { ArrayList dict;   public Dictionary() { StreamReader src = new StreamReader("cedict.b5", System.Text.Encoding.GetEncoding(950)); DictionaryEntry de; dict = new ArrayList();   char[] buffer = new char[40960];   int cb = src.Read(buffer, 0, buffer.Length);   while (cb != 0) { int ibLastNewLine = cb - 1; // Если в буфере нет Enter'а и ibLastNewLine > 0 (проверка "завершенности" последней строки) ) while (buffer[ibLastNewLine] != '\n' && ibLastNewLine > 0) ibLastNewLine--;   if (ibLastNewLine == 0) return;   int ib = 0; // Считает символы while (ib < ibLastNewLine) { // Решетка - знак комментария в факин-файле if (buffer[ib] == '#') { while (buffer[ib] != '\n') ib++; } else { int ibOut; // Превращаем строку в запись словаря   de = DictionaryEntry.ParseBuffer(buffer, ib, ibLastNewLine, out ibOut);   ib = ibOut; // И добавляем запись (если, конечно, есть чего добавить) if (de != null) dict.Add(de); } ib++; } int ibCopy = ibLastNewLine + 1; // Все счастливы... часть файла обработали беремся за следующую ib = 0; while (ibCopy < cb) buffer[ib++] = buffer[ibCopy++];   int cbNew = src.Read(buffer, ib, buffer.Length - ib);   cb = ib + cbNew; } }   public int Length() { return dict.Count; } } } }

Ссылка на "словарь" для теста:http://www.mdbg.net/chindict/export/cedict/cedict_1_0_t_big5_mdbg.zip

Post too large. Как мило :) Все статьи
Part 1 Part 2 Part 3 Part 4

it, c#, c++, С++ vs С#

Previous post Next post
Up