То, что избежать для производительности, рассуждает в многопоточном коде?

Касательно: http://docs.python.org/howto/unicode

Unicode Чтения из файла поэтому прост:

import codecs
f = codecs.open('unicode.rst', encoding='utf-8')
for line in f:
    print repr(line)

также возможно открыть файлы в режиме обновления, позволяя и читая и пишущий:

f = codecs.open('test', encoding='utf-8', mode='w+')
f.write(u'\u4500 blah blah blah\n')
f.seek(0)
print repr(f.readline()[:1])
f.close()

РЕДАКТИРОВАНИЕ : я предполагаю, что Ваша намеченная цель состоит в том, чтобы только быть в состоянии считать файл правильно в строку в Python. При попытке преобразовать в строку ASCII от Unicode, то нет действительно никакого прямого способа сделать так, так как символы Unicode будут не обязательно существовать в ASCII.

, При попытке преобразовать в строку ASCII, попробуйте одно из следующего:

  1. Замена определенные unicode символы с эквивалентами ASCII, если Вы только надеетесь обрабатывать несколько особых случаев, таких как этот конкретный пример

  2. Использование unicodedata модуль normalize() и string.encode() метод для преобразования как лучше всего, Вы можете к следующему ближайшему эквивалентному ASCII (Касательно https://web.archive.org/web/20090228203858/http://techxplorer.com/2006/07/18/converting-unicode-to-ascii-using-python):

    >>> teststr
    u'I don\xe2\x80\x98t like this'
    >>> unicodedata.normalize('NFKD', teststr).encode('ascii', 'ignore')
    'I donat like this'
    

7
задан Jorge Córdoba 9 September 2009 в 14:28
поделиться

12 ответов

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

Например: Если вы используете переменную счетчика для подсчета количества элементов, обработанных всеми потоками, это действительно снизит производительность, потому что строки кэша ЦП должны синхронизироваться всякий раз, когда другой ЦП записывает в переменную.

6
ответ дан 6 December 2019 в 06:14
поделиться

Одна вещь, которая снижает производительность, - это наличие двух потоков с большим доступом к жесткому диску. Жесткий диск перескакивал с предоставления данных для одного потока на другой, и оба потока все время ждали диск.

5
ответ дан 6 December 2019 в 06:14
поделиться

Something to keep in mind when locking: lock for as short a time as possible. For example, instead of this:

lock(syncObject)
{
    bool value = askSomeSharedResourceForSomeValue();
    if (value)
        DoSomethingIfTrue();
    else
        DoSomtehingIfFalse();
}

Do this (if possible):

bool value = false;  

lock(syncObject)
{
    value = askSomeSharedResourceForSomeValue();
}  

if (value)
   DoSomethingIfTrue();
else
   DoSomtehingIfFalse();

Of course, this example only works if DoSomethingIfTrue() and DoSomethingIfFalse() don't require synchronization, but it illustrates this point: locking for as short a time as possible, while maybe not always improving your performance, will improve the safety of your code in that it reduces surface area for synchronization problems.

And in certain cases, it will improve performance. Staying locked for long lengths of time means that other threads waiting for access to some resource are going to be waiting longer.

5
ответ дан 6 December 2019 в 06:14
поделиться

Больше потоков, чем ядер, обычно означает, что программа не работает оптимально.

Таким образом, программа, которая порождает множество потоков, обычно не разработана наилучшим образом. Хорошим примером такой практики являются классические примеры Socket, в которых каждое входящее соединение имеет собственный поток для обработки соединения. Это очень не масштабируемый способ решения задач. Чем больше потоков существует, тем больше времени ОС будет использовать для переключения контекста между потоками.

4
ответ дан 6 December 2019 в 06:14
поделиться

You should first be familiar with Amdahl's law.

If you are using Java, I recommend the book Java Concurrency in Practice; however, most of its help is specific to the Java language (Java 5 or later).

In general, reducing the amount of shared memory increases the amount of parallelism possible, and for performance that should be a major consideration.

Threading with GUI's is another thing to be aware of, but it looks like it is not relevant for this particular problem.

3
ответ дан 6 December 2019 в 06:14
поделиться

What kills performance is when two or more threads share the same resources. This could be an object that both use, or a file that both use, a network both use or a processor that both use. You cannot avoid these dependencies on shared resources but if possible, try to avoid sharing resources.

2
ответ дан 6 December 2019 в 06:14
поделиться

Run-time profilers may not work well with a multi-threaded application. Still, anything that makes a single-threaded application slow will also make a multi-threaded application slow. It may be an idea to run your application as a single-threaded application, and use a profiler, to find out where its performance hotspots (bottlenecks) are.

When it's running as a multi-threaded aplication, you can use the system's performance-monitoring tool to see whether locks are a problem. Assuming that your threads would lock instead of busy-wait, then having 100% CPU for several threads is a sign that locking isn't a problem. Conversely, something that looks like 50% total CPU utilitization on a dual-processor machine is a sign that only one thread is running, and so maybe your locking is a problem that's preventing more than one concurrent thread (when counting the number of CPUs in your machine, beware multi-core and hyperthreading).

Locks aren't only in your code but also in the APIs you use: e.g. the heap manager (whenever you allocate and delete memory), maybe in your logger implementation, maybe in some of the O/S APIs, etc.

Should I start questioning the locks and looking to a lock-free strategy

I always question the locks, but have never used a lock-free strategy; instead my ambition is to use locks where necessary, so that it's always threadsafe but will never deadlock, and to ensure that locks are acquired for a tiny amount of time (e.g. for no more than the amount of time it takes to push or pop a pointer on a thread-safe queue), so that the maximum amount of time that a thread may be blocked is insignificant compared to the time it spends doing useful work.

1
ответ дан 6 December 2019 в 06:14
поделиться

You don't mention the language you're using, so I'll make a general statement on locking. Locking is fairly expensive, especially the naive locking that is native to many languages. In many cases you are reading a shared variable (as opposed to writing). Reading is threadsafe as long as it is not taking place simultaneously with a write. However, you still have to lock it down. The most naive form of this locking is to treat the read and the write as the same type of operation, restricting access to the shared variable from other reads as well as writes. A read/writer lock can dramatically improve performance. One writer, infinite readers. On an app I've worked on, I saw a 35% performance improvement when switching to this construct. If you are working in .NET, the correct lock is the ReaderWriterLockSlim.

1
ответ дан 6 December 2019 в 06:14
поделиться

Я рекомендую рассмотреть возможность запуска нескольких процессов, а не нескольких потоков в одном процессе, если это серверное приложение.

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

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

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

1
ответ дан 6 December 2019 в 06:14
поделиться

Я использую Delphi 7

Вы тогда может использоваться COM-объекты, явно или неявно; если да, то у COM-объектов есть свои сложности и ограничения на многопоточность: Процессы, потоки и апартаменты .

1
ответ дан 6 December 2019 в 06:14
поделиться

You should first get a tool to monitor threads specific to your language, framework and IDE. Your own logger might do fine too (Resume Time, Sleep Time + Duration). From there you can check for bad performing threads that don't execute much or are waiting too long for something to happen, you might want to make the event they are waiting for to occur as early as possible.

As you want to use both cores you should check the usage of the cores with a tool that can graph the processor usage on both cores for your application only, or just make sure your computer is as idle as possible.

Besides that you should profile your application just to make sure that the things performed within the threads are efficient, but watch out for premature optimization. No sense to optimize your multiprocessing if the threads themselves are performing bad.

Looking for a lock-free strategy can help a lot, but it is not always possible to get your application to perform in a lock-free way.

0
ответ дан 6 December 2019 в 06:14
поделиться

Потоки не всегда равны по производительности.

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

0
ответ дан 6 December 2019 в 06:14
поделиться
Другие вопросы по тегам:

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