Генерация Типов Делегата динамично в C#

Большое спасибо @Strawberry и @Solarflare за помощь, предоставленную в комментариях.

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

Я использовал индексы и опрашивал всю таблицу, как они и предлагали.

import sqlite3
from operators import attrgetter

connection = sqlite3.connect("database.db")

# Creating index, thanks to @Solarflare
cursor = connection.cursor()
cursor.execute("CREATE INDEX IF NOT EXISTS idx_user_id ON EVENT_LOG (user_id)")
cursor.commit()

# Reading the whole table, then make lists by user_id. Thanks to @Strawberry
cursor.execute("SELECT user_id, action, timestamp FROM EVENT_LOG ORDER BY user_id ASC")
previous_user_id = None
log_per_user = list()
classified_log = dict()
for row in cursor:
    user_id, action, timestamp = row
    if user_id != previous_user_id:
        if previous_user_id:
            log_per_user.sort(key=itemgetter(1))
            classified_log[previous_user_id] = log_per_user[:]
        log_per_user = list()
    log_per_user.append((action, timestamp))
    previous_user_id = user_id

Таким образом, точки

  • индексируют по user_id, чтобы ORDER BY user_id ASC выполнялось в приемлемое время.
  • Читая всю таблицу, затем классифицируйте по user_id, вместо того, чтобы делать отдельные запросы для каждого user_id.
  • Итерации по cursor для чтения строка за строкой вместо cursor.fetchall().
5
задан BrunoLM 23 September 2010 в 12:32
поделиться

2 ответа

Самый простой способ - использовать существующее семейство делегатов Func .

Использовать typeof (Func <,,,,>). MakeGenericType ( ...) . Например, для вашего типа int Del2 (int, int, string, int) :

using System;

class Test
{
    static void Main()
    {
        Type func = typeof(Func<,,,,>);
        Type generic = func.MakeGenericType
            (typeof(int), typeof(int), typeof(string),
             typeof(int), typeof(int));
        Console.WriteLine(generic);
    }
}

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

РЕДАКТИРОВАТЬ: Как говорит Олсин, типы Func являются частью .NET 3.5 - но если вы хотите использовать их в .NET 2.0, вам просто нужно чтобы объявить их самостоятельно, например, так:

public delegate TResult Func<TResult>();
public delegate TResult Func<T, TResult>(T arg);
public delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);
public delegate TResult Func<T1, T2, T3, TResult>
    (T1 arg1, T2 arg2, T3 arg3);
public delegate TResult Func<T1, T2, T3, T4, TResult>
    (T1 arg1, T2 arg2, T3 arg3, T4 arg4);

Если вам не хватает 4 аргументов, вы, конечно, можете добавить больше.

11
ответ дан 13 December 2019 в 19:35
поделиться

Ответ Джона отлично работает, если вы используете Framework 3.5 (но не все).

Ответ 2.0 заключается в использовании Delegate.CreateDelegate (...)

http://msdn.microsoft.com/en-us/library/system.delegate.createdelegate.aspx

Сравнение различных способы сделать это, включая Func Jon, Delegate.CreateDelegate, DynamicMethods и различные другие приемы, обсуждались в более ранней теме:

Delegate.CreateDelegate против DynamicMethod против Expression

-Oisin

0
ответ дан 13 December 2019 в 19:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: