Есть ли будущее у DELPHI?
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
| ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
| [216.73.216.43] |
|
|
Правила раздела:
| Страницы: (245) « Первая ... 82 83 [84] 85 86 ... 244 245 ( Перейти к последнему сообщению ) |
Есть ли будущее у DELPHI?
|
Сообщ.
#1246
,
|
|
|
|
И кто там победил? Лень перечитывать всю тему Добавлено Для своего проекта, для которого сейчас пишу аналог для .NET - проверил время сериализации в XML 1000 аналогичных объектов. В Delphi процесс занимает меньше секунды. В C# - около 3 секунд. Тут конечно можно говорить что мол код, выполняющий эти действия - по реализации совсем не аналогичен, но как бы и тот и другой использует стандартные инструменты Меня как бы именно с это точки зрения производительность интересует - реальные инструменты в реальных проектах, при реальных условиях, а не неких предполагаемых... |
|
Сообщ.
#1247
,
|
|
|
|
Цитата --Ins-- @ И кто там победил? Лень перечитывать всю тему В двух случаях Delphi (без сортировки), в двух случаях C++ (с сортировкой). |
|
Сообщ.
#1248
,
|
|
|
|
Итак - новый тест для Java, C# и Delphi.
Берем файл вида ![]() ![]() Категория 8;Подкатегория 82;Элемент 9 Категория 1;Подкатегория 65;Элемент 62 Категория 8;Подкатегория 129;Элемент 183 Категория 16;Подкатегория 1;Элемент 2 Категория 10;Подкатегория 60;Элемент 86 Категория 11;Подкатегория 118;Элемент 71 Категория 11;Подкатегория 28;Элемент 137 Категория 13;Подкатегория 4;Элемент 100 Категория 12;Подкатегория 30;Элемент 129 Категория 1;Подкатегория 1;Элемент 10 Категория 17;Подкатегория 60;Элемент 133 Категория 19;Подкатегория 49;Элемент 9 Категория 10;Подкатегория 64;Элемент 43 Категория 2;Подкатегория 62;Элемент 27 ... На выходе получаем: ![]() ![]() Категория 8 Подкатегория 82 Элемент 9 Элемент 107 Элемент 114 Элемент 75 Элемент 118 Элемент 136 Элемент 188 Элемент 161 Элемент 4 Элемент 123 ... Для тестов бралось 2 файла - 6,70 МБ и 64,7 МБ. Delphi: ![]() ![]() program Tree; {$APPTYPE CONSOLE} uses Windows, Classes, SysUtils, IniFiles, Generics.Collections; function ExtractSubstr(const Value: string): TStrings; var C: Char; S: string; begin Result := TStringList.Create; S := ''; for C in Value do begin if C = ';' then begin Result.Add(S); S := ''; end else begin S := S + C; end; end; if S <> '' then Result.Add(S); end; var AppPath, SourcePath: string; type TStringDictionary = class(TObjectDictionary<string, TObject>) public constructor Create; reintroduce; end; { TStringDictionary } constructor TStringDictionary.Create; begin inherited Create([doOwnsValues]); end; procedure ProcessFile(const FileName: string; Source: TStrings); procedure LoadFile(Source: TStrings; Dest: TStringDictionary); function InsertStringToList(const S: string; List: TStringDictionary): TStringDictionary; begin if not List.ContainsKey(S) then begin Result := TStringDictionary.Create; List.Add(S, Result); end else Result := TStringDictionary(List[S]); end; var S, Category, SubCategory, Element: string; Parts: TStrings; begin for S in Source do begin Parts := ExtractSubstr(S); Category := Parts[0]; SubCategory := Parts[1]; Element := Parts[2]; Parts.Free; with InsertStringToList(SubCategory, InsertStringToList(Category, Dest)) do Add(Element, nil); end; end; procedure SaveAsTree(Root: TStringDictionary; Dest: TStrings); function Space(Num: Integer): string; var I: Integer; begin Result := ''; for I := 1 to Num do Result := Result + #32; end; procedure Output(L: TStringDictionary; Level: Integer); var S: string; SubList: TStringDictionary; begin for S in L.Keys do begin if Level > 0 then Dest.Add(Space(Level * 2) + S) else Dest.Add(S); SubList := TStringDictionary(L[S]); if SubList <> nil then Output(SubList, Level + 1); end; end; begin Output(Root, 0); end; var Root: TStringDictionary; Dest: TStrings; Time: Cardinal; S, OutFile: string; begin Root := TStringDictionary.Create; Dest := TStringList.Create; Time := GetTickCount; LoadFile(Source, Root); SaveAsTree(Root, Dest); Time := GetTickCount - Time; S := FileName + ' generic: '; OutFile := AppPath + FileName; WriteLn(S, Time); Dest.SaveToFile(OutFile); Dest.Free; Root.Free; end; procedure Test(const FileName: string); var Source: TStrings; begin Source := TStringList.Create; Source.LoadFromFile(SourcePath + FileName); ProcessFile(FileName, Source); Source.Free; end; begin AppPath := ExtractFilePath(ParamStr(0)); SourcePath := IncludeTrailingPathDelimiter(ExtractFilePath(ExcludeTrailingPathDelimiter(AppPath)) + '_TestFiles'); Test('test'); Test('test2'); Readln; end. Результат: ![]() ![]() test generic: 452 test2 generic: 4571 C# ![]() ![]() using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Reflection; using System.IO; namespace ConsoleApplication1 { class StringDictionary : Dictionary<String, StringDictionary> { } class Main { private List<String> ExtractSubstr(String Value) { List<String> Result = new List<String>(); String S = ""; foreach (char C in Value.ToCharArray()) { if (C == ';') { Result.Add(S); S = ""; } else { S += C; } } if (S != "") { Result.Add(S); } return Result; } private String Space(int Num) { String Result = ""; for (int i = 1; i <= Num; i++) { Result += " "; } return Result; } private StringDictionary InsertStringList(String S, StringDictionary List) { StringDictionary Result; if (!List.TryGetValue(S, out Result)) { Result = new StringDictionary(); List.Add(S, Result); } return Result; } private void LoadFile(List<String> Source, StringDictionary Dest) { foreach (String S in Source) { List<String> Parts = ExtractSubstr(S); String Category = Parts[0]; String SubCategory = Parts[1]; String Element = Parts[2]; InsertStringList(SubCategory, InsertStringList(Category, Dest)) .Add(Element, null); } } private void Output(StringDictionary L, List<String> Dest, int Level) { foreach (String S in L.Keys) { if (Level > 0) { Dest.Add(Space(Level * 2) + S); } else { Dest.Add(S); } StringDictionary SubList = L[S]; if (SubList != null) { Output(SubList, Dest, Level + 1); } } } private void SaveAsTree(StringDictionary Root, List<String> Dest) { Output(Root, Dest, 0); } public void ProcessFile(String FileName, List<String> Source) { StringDictionary Root = new StringDictionary(); List<String> Dest = new List<String>(); long Time = System.Environment.TickCount; LoadFile(Source, Root); SaveAsTree(Root, Dest); Time = System.Environment.TickCount - Time; String S = FileName + " generic: "; String OutFile = AppPath + FileName; Console.WriteLine(S + Time); using (System.IO.StreamWriter file = new System.IO.StreamWriter(OutFile, false, System.Text.Encoding.GetEncoding(1251))) { foreach (string line in Dest) { file.WriteLine(line); } } } private void Test(String FileName) { List<String> Source = new List<String>(); string[] lines = System.IO.File.ReadAllLines(SourcePath + FileName); Source.AddRange(lines); ProcessFile(FileName, Source); } private String AppPath, SourcePath; public Main() { AppPath = Path.GetDirectoryName(Assembly.GetAssembly(typeof(Main)).CodeBase); AppPath = AppPath.Substring(6) + "\\"; DirectoryInfo di = new DirectoryInfo(AppPath); SourcePath = di.Parent.Parent.Parent.Parent.FullName + "\\_TestFiles\\"; Test("test"); Test("test2"); Console.ReadLine(); } } class Program { static void Main(string[] args) { new Main(); } } } ![]() ![]() test generic: 531 test2 generic: 7847 Java: ![]() ![]() package main; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.Writer; import java.util.ArrayList; import java.util.HashMap; import java.util.List; public class Main { private class StringDictionary extends HashMap<String, StringDictionary> { private static final long serialVersionUID = 1L; } private class ProcessFile { private StringDictionary InsertStringList(String S, StringDictionary List) { if (!List.containsKey(S)) { StringDictionary Result = new StringDictionary(); List.put(S, Result); return Result; } else { return List.get(S); } } private void LoadFile(List<String> Source, StringDictionary Dest) { for (String S : Source) { List<String> Parts = ExtractSubstr(S); String Category = Parts.get(0); String SubCategory = Parts.get(1); String Element = Parts.get(2); InsertStringList(SubCategory, InsertStringList(Category, Dest)) .put(Element, null); } } private void Output(StringDictionary L, List<String> Dest, int Level) { for (String S : L.keySet()) { if (Level > 0) { Dest.add(Space(Level * 2) + S); } else { Dest.add(S); } StringDictionary SubList = L.get(S); if (SubList != null) { Output(SubList, Dest, Level + 1); } } } private void SaveAsTree(StringDictionary Root, List<String> Dest) { Output(Root, Dest, 0); } public ProcessFile(String FileName, List<String> Source) { StringDictionary Root = new StringDictionary(); List<String> Dest = new ArrayList<String>(); long Time = System.currentTimeMillis(); LoadFile(Source, Root); SaveAsTree(Root, Dest); Time = System.currentTimeMillis() - Time; String S = FileName + " generic: "; String OutFile = AppPath + FileName; System.out.println(S + Time); try { Writer output = new BufferedWriter(new FileWriter(OutFile)); try { for (String line : Dest) { output.write(line); output.write(System.getProperty("line.separator")); } } finally { output.close(); } } catch (IOException e) { e.printStackTrace(); } } } private List<String> ExtractSubstr(String Value) { List<String> Result = new ArrayList<String>(); String S = ""; for (char C : Value.toCharArray()) { if (C == ';') { Result.add(S); S = ""; } else { S += C; } } if (S != "") { Result.add(S); } return Result; } private String Space(int Num) { String Result = ""; for (int i = 1; i <= Num; i++) { Result += " "; } return Result; } private void Test(String FileName) { List<String> Source = new ArrayList<String>(); try { BufferedReader input = new BufferedReader(new FileReader(SourcePath + FileName)); try { String line; while ((line = input.readLine()) != null) { Source.add(line); } } finally { input.close(); } } catch (IOException e){ e.printStackTrace(); } new ProcessFile(FileName, Source); } private String AppPath, SourcePath; public Main() { String Separator = System.getProperty("file.separator"); AppPath = System.getProperty("java.class.path") + Separator; System.out.println(AppPath); File dir = new File(AppPath); SourcePath = dir.getParent(); dir = new File(SourcePath); SourcePath = dir.getParent() + Separator + "_TestFiles" + Separator; System.out.println(AppPath); System.out.println(SourcePath); Test("test"); Test("test2"); } public static void main(String[] args) { new Main(); } } ![]() ![]() test generic: 451 test2 generic: 4426 Таким образом, с небольшим отрывом побеждает Java. Но преимущество на грани статистической погрешности, так что однозначного первенства нету. Но сам факт, что язык с управляемым кодом бьет "нативный" Delphi - многое о чем говорит. Обращаю также внимание на ущербный Delphi-синтаксис: ![]() ![]() type TStringDictionary = class(TObjectDictionary<string, TObject>) public constructor Create; reintroduce; end; Почему я не могу объявить TStringDictionary = class(TObjectDictionary<string, TStringDictionary>) как во всех нормальных языках? И нужно извращаться с тайпкастами. Вот это я и называю ущербными дженериками А вот Шарп таки прилично сливает. Особенно на большом файле - почти в 2 раза. |
|
Сообщ.
#1249
,
|
|
|
|
Цитата [S]mike @ Почему я не могу объявить TStringDictionary = class(TObjectDictionary<string, TStringDictionary>) Так ты же параметры конструктора меняешь, если я правильно понял? Тут кстати недавно спор был по этому поводу, что я обязан переобъявлять конструкторы потомков в шарпе. Мне пытались доказать что это нормально и мол так и нужно, а вот как в Delphi - когда конструкторы наследуются - так это неправильно Добавлено Цитата [S]mike @ А вот Шарп таки прилично сливает. Особенно на большом файле - почти в 2 раза. Еще одно подтверждение, что для win-gui пока ничего лучше Delphi еще не придумали |
|
Сообщ.
#1250
,
|
|
|
|
Цитата [S]mike @ А вот Шарп таки прилично сливает. Особенно на большом файле - почти в 2 раза. Со строками обычно так не работаю, поскольку они неизменяемые. Формируя строку посимвольно с помощью конкатенации ты их столько наплодишь. Поэтому используют StringBuilder, у него внутри буфер из симоволов. |
|
Сообщ.
#1251
,
|
|
|
|
Цитата --Ins-- @ Так ты же параметры конструктора меняешь, если я правильно понял? Оно и без этого не работает ![]() Цитата --Ins-- @ Еще одно подтверждение, что для win-gui пока ничего лучше Delphi еще не придумали ![]() Ну а в предыдущем тесте Шарп был быстрее дельфей ![]() Цитата Red @ Со строками обычно так не работаю, поскольку они неизменяемые. Формируя строку посимвольно с помощью конкатенации ты их столько наплодишь. Я использовал не самые оптимальные алгоритмы специально. Они _одинаковые_ для всех языков и дают общее представление о производительности. |
|
Сообщ.
#1252
,
|
|
|
|
Цитата [S]mike @ Я использовал не самые оптимальные алгоритмы специально. Они _одинаковые_ для всех языков и дают общее представление о производительности. Зачем сравнивать плохие реализации, если в реальности стараются использовать нормальные? |
|
Сообщ.
#1253
,
|
|
|
|
Цитата [S]mike @ Ну а в предыдущем тесте Шарп был быстрее дельфей Предыдущим был мой с сериализацией И честно говоря он для меня самый важный |
|
Сообщ.
#1254
,
|
|
|
|
Цитата [S]mike @ Цитата Red @ Со строками обычно так не работаю, поскольку они неизменяемые. Формируя строку посимвольно с помощью конкатенации ты их столько наплодишь. Я использовал не самые оптимальные алгоритмы специально. Они _одинаковые_ для всех языков и дают общее представление о производительности. Вот поэтому я и говорю "есть ложь, есть наглая ложь и есть бенчмарки" © не я |
|
Сообщ.
#1255
,
|
|
|
|
Цитата [S]mike @ Не знаю, что там твои бенчмарки. Но вижула, написанная на шарпе работает неделями. А вот эклипс, или нетбинс на яве уже на второй день очень, очень настойчиво намекает на то, что его надо бы перезапустить. Я использовал не самые оптимальные алгоритмы специально. Они _одинаковые_ для всех языков и дают общее представление о производительности. Добавлено А ещё у нас есть такая штука, как AccuRev. Тоже на яве. Более тормозного софта я не видывал ни разу в жизни! Добавлено Мне вообще на яве не доводилось видывать не тормозящего софта. Разве что аппликухи под телефоны. Добавлено Но и с аппликухами не всё так гладко. Пока не вышел андроид с явовскими фреймвёрками никому и в голову не приходило пытаться запихнуть в телефон двухядерные процы. |
|
Сообщ.
#1256
,
|
|
|
|
Цитата Повстанець @ Не знаю, что там твои бенчмарки. Но вижула, написанная на шарпе работает неделями. А вот эклипс, или нетбинс на яве уже на второй день очень, очень настойчиво намекает на то, что его надо бы перезапустить. Есть мнение, что это плохо написанные на java приложения. Та же IDEA не тормозит(по крайне мере у меня). Цитата Но и с аппликухами не всё так гладко. Пока не вышел андроид с явовскими фреймвёрками никому и в голову не приходило пытаться запихнуть в телефон двухядерные процы. Мне вот кажется, что называть андроидовскую вирутальную машину ява-машиной неправильно, она отличается достаточно сильно с т.з. архитектуры, байткода и т.п. |
|
Сообщ.
#1257
,
|
|
|
|
Цитата D_KEY @ Есть мнение, что это плохо написанные на java приложения. Интересно, а Minecraft - это плохо написанное java-приложение, или хорошо написанное? |
|
Сообщ.
#1258
,
|
|
|
|
Цитата --Ins-- @ Цитата D_KEY @ Есть мнение, что это плохо написанные на java приложения. Интересно, а Minecraft - это плохо написанное java-приложение, или хорошо написанное? Там же на разных языках вроде разные клиенты написаны. Но вообще я не знаю, даже не пробовал. Только на ютубе видел извращенцев, создающих в minecraft компы из логических элементов |
|
Сообщ.
#1259
,
|
|
|
|
Цитата D_KEY @ Там же на разных языках вроде разные клиенты написаны. Это Java. У меня даже исходники есть Игрушка то классная, но лагает и требует чрезмерно много ресурсов |
|
Сообщ.
#1260
,
|
|
|
|
Цитата OpenOffice в принципе не сильно тормозит. Но это исключение Мне вообще на яве не доводилось видывать не тормозящего софта. ![]() Цитата промучался с ним 2 года...не думал, что его еще где-то юзают оО заказчики случаем не из Бурлингтона? А ещё у нас есть такая штука, как AccuRev. |