Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: DictRepositoryItems: TDictionary<String, TcxEditRepositoryItem>; // как?

Доброго времени суток.

подскажите плиз, хочу создать словарь типа (название поля + едит с репозитория)

  // редактор по имени поля
  DictRepositoryItems:=TDictionary<String, TcxEditRepositoryItem>; 
  with DictRepositoryItems do
    begin
    Add('data', EdRepImage);  // картинка
    end;


ругает при
DictRepositoryItems:=TDictionary<String, TcxEditRepositoryItem>; 

dcc32 Error, DataUnit.pas(126):
E2010 Incompatible types: 'System.Generics.Collections.TDictionary<System.string,cxEdit.TcxEditRepositoryItem>' and 'class of System.Generics.Collections.TDictionary<System.string,cxEdit.TcxEditRepositoryItem>'


что не так? никак не могу понять....
Ответ: Наступает синтаксический диабет.
Вопрос: TDictionary удалить ключи по значению ключа

Использую TDictionary для связи сгруппированных элементов в памяти с их отображением в дереве TDictionary<Element, Node>. Т.е.
Element1 -> Node1
Element2 -> Node1
Element3 -> Node1
Element4 -> Node2
итд

Допустим я удалил Node1 и мне нужно удалить из словаря все ключи ссылающиеся на Node1. Это можно как-то сделать без прохода по всему словарю?
Ответ: Кстати в TObjectDictionary есть бага/фича, правда весьма специфичная и редко встречающаяся: как бы никто не запрещает использовать в качестве одного и того же значения ключа разные объекты, которым должно соответствовать одно и то же значение из словаря (реализуется перекрытием GetHashCode, Equals). Так вот в этом случае при попытке удалить значение по ключу при doOwnsKeys, будет прибиваться передаваемый класс-ключ, а не тот объект, который был добавлен в словарь вместе со значением - по сути будет утечка памяти. Но повторюсь, ситуация довольно редкая, но мы разок напоролись, в одной из реализаций кеша уникальных данных
Вопрос: TDictionary memory leak

Доброго времени суток, коллеги!
Кто разбирался с дженериками? Подскажите, пожалуйста, почему идёт утечка памяти?
Используется XE7 Upd1 (21.0.17707.5020)
+

program test;

{$APPTYPE CONSOLE}

uses System.Generics.Collections;

type

  TFirstObject = class(TObject)
  private
    fStr: String;
  public
    constructor Create(const AStr : String = '');
    property Str : String read fStr;
  end;

{ TFirstObject }

constructor TFirstObject.Create(const AStr: String = '');
begin
  inherited Create;
  fStr := AStr;
end;

procedure FreeAndNil(var Obj);
var
  Temp: TObject;
begin
  Temp := TObject(Obj);
  Pointer(Obj) := nil;
  Temp.Free;
end;

var dic : TDictionary<Integer, TFirstObject>;

begin
{$IFDEF DEBUG}
  ReportMemoryLeaksOnShutdown := True;
{$ENDIF}

  dic := TDictionary<Integer, TFirstObject>.Create;
  dic.Add(1,  TFirstObject.Create('первый') );
  dic.Add(5,  TFirstObject.Create('пятый') );
  dic.Add(3,  TFirstObject.Create );
  dic.Add(2,  TFirstObject.Create('второй') );
  dic.Add(4,  TFirstObject.Create );
  Writeln('cnt=',dic.Count);
  Writeln('5  =', dic.Items[5].Str);
  Writeln('3  =', dic.Items[3].Str);
  FreeAndNil(dic);  // !!!! memory leak
end.

Ответ: dic := TObjectDictionary<Integer, TFirstObject>.Create([doOwnsValues]);
спасло, спасибо за наводку
Вопрос: THashedStringList vs TDictionary<string>

Есть у меня ini файл. В файле порядка 300 секций, в каждой секции 9 ключей. Для работы использовал TMemIniFile. На чтение всех настроек уходило 1200 мс. TMemIniFile использует внутри THashedStringList. Переписал на TDictionary, получил время чтения 370 мс. Так и должно было быть?

Delphi XE3

С уважением, Vasilisk
Ответ:
defecator
Если у тебя есть DevExpress, посмотри в модуле dxServerModeClasses.pas,
папка \ExpressDataController\Sources
Спасибо, посмотрю.
Первое впечатление - выглядит всё слишком очень просто. Неужели выигрыш только в отсутствии дженериков, отсутствии интефейсов и другой хэш-функции?
Вопрос: Косяк TDictionary с рекордами со строками

Delphi XE5
Генерит хэш для одинаковых (по содержанию) записей разный, изза чего невозможно пользоваться методом AddOrSetValue или подобными, так как ключи считаются разными.
Тест для воспроизведения:
+
Uses ..
 System.Generics.Defaults, System.Generics.Collections;
procedure TestDictionary;
type
  TGisData = record
    Sign: string;
//    Sign: Char;
    SaleTime: TDateTime;
  end;
  TGISDict = TDictionary<TGisData, Double>;
const
  c1 = 'я';
var
  GIS_Dict: TGISDict;
  data: TGisData;
begin
  GIS_Dict := TGISDict.Create;
  try
    data.Sign := c1;
    data.SaleTime := 5000;
    GIS_Dict.AddOrSetValue(data, 2);

    data.Sign := c1;
    data.SaleTime := 5000;
    GIS_Dict.AddOrSetValue(data, 3);
    ShowMessage(IntToStr(GIS_Dict.Count));


    data.Sign := c1 + c1;
    data.SaleTime := 5000;
    GIS_Dict.AddOrSetValue(data, 2);

    data.Sign := c1 + c1;
    data.SaleTime := 5000;
    GIS_Dict.AddOrSetValue(data, 3);
    ShowMessage(IntToStr(GIS_Dict.Count));
  finally
    GIS_Dict.Free;
  end;
end;


Подскажите, кто как выходил из такой же ситуации?
Ответ:
Вопрос: Многомерный ассоциативный динамический массив с помощью TDictionary. Как?

Всем привет. Работаю с TDictionary но на примитивном уровне, типа списки ключ-значение, простые списки в общем. Подскажите как перейти на новый уровень :-) Хочу стать джедаем динамических многомерных массивов. Может у кого есть примеры кода или поделитесь ссылками на хорошие статьи/примеры? Буду очень признателен.

О чём вообще речь. Сейчас есть простые списки, типа "Учебники"-"География,Математика и т.д...". А нужны многомерные, динамические и ассоциативные (чтобы по имени).

И вот как работать через TDictionary по схожему принципу, как с массивами по типу PHP?
Т.е. хочу добавил простой список как сейчас: "Учебники"-"География,Математика и т.д...".
А хочу, добавил список массивов списков:
Школа:
"Учебники1"-"География,Математика и т.д...".
"Учебники2"-"География,Математика и т.д...".
Школа2:
"Учебники1"-"География,Математика и т.д...".
"Учебники2"-"География,Математика и т.д...".
"Учебники3"-"География,Математика и т.д...".
Ответ: Спасибо за идеи, буду разбираться. Полезные примеры, смысл понял!
Вопрос: Производительность контейнеров stl для игры

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

Что я имею в виду: чтобы проверить, столкнулись объекты или нет, надо сравнить координаты каждого с каждым. Запускаю игру, начинаю добавлять объекты по 50 штук. Все игровые объекты кладутся в контейнер. Изначально был контейнер deque. Но он держал только 150 объектов (при двойном проходе по контейнеру с помощью for с индексами (код блока Before).

Поставил vector. При аналогичном проходе игра выдержала 350 объектов. Заменил проход с индексов на итераторы:

Код C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
            //Before
            for (int i = 0; i < container.size(); i++) {
                if (container[i]->events->CollisionEvent) {
                    for (int k = i + 1; k < container.size(); k++) {
                        container[i]->events->CollisionEvent;
                        if (container[k]->events->CollisionEvent &&
                            IsCollide(container[i]->obj, container[k]->obj)) {
 
                        }
                    }
                }
            }
 
            //After
            for (auto i = container.begin(); i != container.end(); i++) {
                if ((*i)->events->CollisionEvent) {
                    for (auto k = i + 1; k != container.end(); k++) {
                        (*k)->events->CollisionEvent;
                        if ((*k)->events->CollisionEvent &&
                            IsCollide((*i)->obj, (*k)->obj)) {
 
                        }
                    }
                }
            }
И меня удивило то, что при втором варианте игра выдержала только 100 объектов. Это даже хуже, чем дек!
Почему при, так сказать, крестьянской индексации, которая выполняется несколько раз в каждой итерации, прога выдает большую производительность, чем когда мы только один раз за итерацию берем итератор, а потом только переходим по этому указателю? Именно из-за этого я и создал сабж. Почему так происходит?

При том, что когда проход вот такой:

Код C++
1
2
3
4
5
6
7
8
9
10
for (auto it : container) {
                if (it->events->CollisionEvent) {
                    for (auto it2 : container) {
                        if (it2->events->CollisionEvent &&
                            IsCollide(it->obj, it2->obj)) {
 
                        }
                    }
                }
            }
То есть тоже через итераторы, то здесь прога держит 200 объектов. При том, что здесь выполняется n^2 сравнений, а не n*(n+1)/2, как в предыдущий вариантах.
Т.е. в 2 раза больше операций, но в 2 раза выше производительность. При том, что это тоже проход через итераторы. В общем, я уже ничего не понимаю, помогите =)

Ну и также хотелось бы услышать советы по поводу, как здесь лучше всё организовать (Какой контейнер лучше, и как его юзать, чтоб побольше производительность была)

P.S.
Кстати, хочу сказать, что функция IsCollide(...) просто возвращает false. Я ее, в общем-то, реализовал, но как начались проблемы с фризами, понял, что лучше пока без нее. Так что она на тесты производительности проходов по контейнеру не влияет.

P.P.S.
И "выдержала n объектов" - в смысле, если после этого числа я добавляю еще 50 объектов, то игра фризится (Хотя сама-то игра работает, но она уже слишком занята проверками коллайда, так что больше не рендерит картинку)
Ответ:
Сообщение от Defake
Почему при, так сказать, крестьянской индексации, которая выполняется несколько раз в каждой итерации, прога выдает большую производительность, чем когда мы только один раз за итерацию берем итератор, а потом только переходим по этому указателю?
Дебаг-сборка? Индекс увеличивается напрямую, итератор через вызов своих методов. Соответственно, если эти вызовы не заинлайнятся, будут дополнительные тормоза. А в дебаг-сборке они как раз таки могут не заинлайнится, ибо все оптимизации вырублены.
Вопрос: Есть ли преимущество в производительности у автосвойств?

Помогите разобраться, в каком виде свойства эффективнее с точки зрения производительности
Код C#
1
2
3
4
5
6
7
8
9
10
public int Month
    {
        get
        {
            return month;
        }
        set
        {
          month = value;   
        }
Код C#
1
2
3
4
5
 public int Month
    {
        get;
        set;
     }
Или же вообще лучше писать самому функции доступа?
Ответ:
если хочешь производительность вообще не используй свойства, обращение к ним где-то на 30-40% медленней чем к голым полям
насколько я знаю, обращение к голым полям это нарушение инкапсуляции
Вопрос: Есть ли прирост производительности от 64-bit на XE8?

Сейчас в клиент-серверном приложении загрузка ЦП практически всегда 100%. Почти все уходит на обработку докучи сетевых запросов.

Интересует будет ли выигрыш в производительности если компилировать в 64-bit платформе?
Ответ: rgreat,

че-то мне в этом топике постоянно в голову лезет история про мэйнфэймы IBM, у которых цена зависела от производительности - там специальный "тормозитель" был в коде, а его коэффициент прошивался в ПЗУ перед продажей.
может это и байка, но в те времена было очень правдоподобным.
Вопрос: Анализ производительности кода

Всем привет!

Написал парсер на simplehtmldom, но время отработки скрипта что-то слишком огромное, от чего возник такой вопрос.
А какие есть толковые инструменты для анализа производительности? Чем можна замерять процесс выполнения кода чтобы хотя бы приблизительно знать где в скрипте узкие места и где надо поработать над оптимизацией? Видел Blackfire.io, но он дороговат для меня...Может есть что-то более-менее приличное и что может вписаться в бюджет на такое до 10 баксов единоразово?
Ответ: Заморочился, переписал парсер на DomCrawler, старые на SimpleHTMLDom не удалял.
Замерил один и тот же код написанный с SHD и DC для сравнения, не то что виртуальная выборка а прям реальный тест с реальными данными
Bash
1
2
SHD: [Done] exited with code=0 in 266.679 seconds
DC: [Done] exited with code=0 in 36.135 seconds
Если я еще из кода уберу дерганья к курсам валют(на каждый перевод создаю новое дом-дерево с сайтом-донором курсов) и вынесу их вне цикла, куда-то в другое место откуда в код буду брать данные и производить калькуляции - чувствую все будет еще веселее.
Немного позже проверю, интереса ради и "на память потомкам".

Добавлено через 11 часов 48 минут
Хотел я все-таки изначально пинать на то, что у меня в каждом проходе цикла обращения к сайту валют и каждый раз туда по три раза дергаю SimpleHTMLDom за валютами, а итог оказался другой - он просто тормоз а на производительность сильно не повлиял вынос валют вне цикла а внутри расчеты по курсу от руки
было 87 секунд стало 62, в то время как при таких же условиях DomCrawler отрабатывает за 35-40 и 8-10 секунд соответственно