mirror of
https://github.com/ankitects/anki.git
synced 2025-09-19 14:32:22 -04:00
add index for groupId, improve startup speed
- skip updating buried cards on startup; it's expensive and we'll do that on deck close in the future - add an index for groupId. Initial profiling indicates that groupId-based selective study is considerably faster in certain scenarios The 50k element deck I'm testing with now opens and builds the queue in 40ms on a cold cache, of which 34ms is the initial deck startup and 6ms the queue build. Adding back the undo log and backups will of course increase this, but this is a big improvement for checking due times in the deck browser.
This commit is contained in:
parent
bb79b0e17c
commit
b3ee91a9d5
3 changed files with 25 additions and 37 deletions
|
@ -15,8 +15,7 @@ NEW_CARDS_DUE = 1
|
|||
|
||||
# sort order for day's new cards
|
||||
NEW_TODAY_ORDINAL = 0
|
||||
NEW_TODAY_FACT = 1
|
||||
NEW_TODAY_DUE = 2
|
||||
NEW_TODAY_DUE = 1
|
||||
|
||||
# review card sort order
|
||||
REV_CARDS_OLD_FIRST = 0
|
||||
|
|
|
@ -105,7 +105,6 @@ class Deck(object):
|
|||
self.reps = 0
|
||||
self.sched = Scheduler(self)
|
||||
|
||||
|
||||
def modifiedSinceSave(self):
|
||||
return self.modified > self.lastLoaded
|
||||
|
||||
|
@ -2637,11 +2636,9 @@ seq > :s and seq <= :e order by seq desc""", s=start, e=end)
|
|||
required = []
|
||||
if self.limits['newTodayOrder'] == NEW_TODAY_ORDINAL:
|
||||
required.append("ordinal")
|
||||
elif self.limits['newTodayOrder'] == NEW_TODAY_FACT:
|
||||
required.append("factId")
|
||||
if self.config['revCardOrder'] in (REV_CARDS_OLD_FIRST, REV_CARDS_NEW_FIRST):
|
||||
required.append("interval")
|
||||
cols = ["queue", "due"] + required
|
||||
cols = ["queue", "due", "groupId"] + required
|
||||
# update if changed
|
||||
if self.db.scalar(
|
||||
"select 1 from sqlite_master where name = 'ix_cards_multi'"):
|
||||
|
|
|
@ -21,12 +21,6 @@ class Scheduler(object):
|
|||
self.queueLimit = 200
|
||||
self.learnLimit = 1000
|
||||
self.updateCutoff()
|
||||
# restore any cards temporarily suspended by alternate schedulers
|
||||
try:
|
||||
self.resetSchedBuried()
|
||||
except OperationalError, e:
|
||||
# will fail if deck hasn't been upgraded yet
|
||||
print "resetSched() failed"
|
||||
|
||||
def getCard(self, orm=True):
|
||||
"Pop the next card from the queue. None if finished."
|
||||
|
@ -39,9 +33,13 @@ class Scheduler(object):
|
|||
|
||||
def reset(self):
|
||||
self.resetConfig()
|
||||
t = time.time()
|
||||
self.resetLearn()
|
||||
print "lrn %0.2fms" % ((time.time() - t)*1000); t = time.time()
|
||||
self.resetReview()
|
||||
print "rev %0.2fms" % ((time.time() - t)*1000); t = time.time()
|
||||
self.resetNew()
|
||||
print "new %0.2fms" % ((time.time() - t)*1000); t = time.time()
|
||||
|
||||
def answerCard(self, card, ease):
|
||||
if card.queue == 0:
|
||||
|
@ -103,11 +101,10 @@ class Scheduler(object):
|
|||
self.newQueue = []
|
||||
self.newCount = 0
|
||||
else:
|
||||
self.newQueue = self.db.all(
|
||||
self.cardLimit(
|
||||
"newActive", "newInactive", """
|
||||
select id, %s from cards c where
|
||||
queue = 2 order by due limit %d""" % (self.newOrder(), lim)))
|
||||
self.newQueue = self.db.all("""
|
||||
select id %s from cards where
|
||||
queue = 2 %s order by due limit %d""" % (self.newOrder(), self.groupLimit('new'),
|
||||
lim))
|
||||
self.newQueue.sort(key=itemgetter(1), reverse=True)
|
||||
self.newCount = len(self.newQueue)
|
||||
self.updateNewCardRatio()
|
||||
|
@ -117,10 +114,7 @@ queue = 2 order by due limit %d""" % (self.newOrder(), lim)))
|
|||
return self.newQueue.pop()[0]
|
||||
|
||||
def newOrder(self):
|
||||
return ("ordinal",
|
||||
"factId",
|
||||
"due",
|
||||
)[self.deck.limits['newTodayOrder']]
|
||||
return (",ordinal", "")[self.deck.limits['newTodayOrder']]
|
||||
|
||||
def updateNewCardRatio(self):
|
||||
if self.deck.config['newCardSpacing'] == NEW_CARDS_DISTRIBUTE:
|
||||
|
@ -215,12 +209,13 @@ limit %d""" % self.learnLimit, lim=self.dayCutoff)
|
|||
##########################################################################
|
||||
|
||||
def resetReview(self):
|
||||
self.revCount = self.db.scalar(
|
||||
self.cardLimit(
|
||||
"revActive", "revInactive",
|
||||
"select count(*) from cards c where queue = 1 "
|
||||
"and due < :lim"), lim=self.dayCutoff)
|
||||
self.revQueue = []
|
||||
self.revQueue = self.db.all("""
|
||||
select id from cards where
|
||||
queue = 1 %s and due < :lim order by %s limit %d""" % (
|
||||
self.groupLimit("rev"), self.revOrder(), self.queueLimit),
|
||||
lim=self.dayCutoff)
|
||||
self.revQueue.reverse()
|
||||
self.revCount = len(self.revQueue)
|
||||
|
||||
def getReviewCard(self):
|
||||
if self.haveRevCards():
|
||||
|
@ -232,21 +227,13 @@ limit %d""" % self.learnLimit, lim=self.dayCutoff)
|
|||
self.fillRevQueue()
|
||||
return self.revQueue
|
||||
|
||||
def fillRevQueue(self):
|
||||
self.revQueue = self.db.all(
|
||||
self.cardLimit(
|
||||
"revActive", "revInactive", """
|
||||
select c.id, factId from cards c where
|
||||
queue = 1 and due < :lim order by %s
|
||||
limit %d""" % (self.revOrder(), self.queueLimit)), lim=self.dayCutoff)
|
||||
self.revQueue.reverse()
|
||||
|
||||
# FIXME: current random order won't work with new spacing
|
||||
# FIXME: limits for new, config for rev is strange atm
|
||||
def revOrder(self):
|
||||
return ("interval desc",
|
||||
"interval",
|
||||
"due",
|
||||
"factId, ordinal")[self.revCardOrder]
|
||||
"factId, ordinal")[self.deck.config['revCardOrder']]
|
||||
|
||||
# FIXME: rewrite
|
||||
def showFailedLast(self):
|
||||
|
@ -492,6 +479,11 @@ and queue between 1 and 2""",
|
|||
self.db.statement(
|
||||
"update cards set queue = type where queue = -3")
|
||||
|
||||
def groupLimit(self, type):
|
||||
#return " and groupId in (1)"
|
||||
print "fixme: groupLimit()"
|
||||
return ""
|
||||
|
||||
def cardLimit(self, active, inactive, sql):
|
||||
yes = parseTags(self.deck.limits.get(active))
|
||||
no = parseTags(self.deck.limits.get(inactive))
|
||||
|
|
Loading…
Reference in a new issue