Большое спасибо @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()
. Самый простой способ - использовать существующее семейство делегатов 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 аргументов, вы, конечно, можете добавить больше.
Ответ Джона отлично работает, если вы используете 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