Re[6]: [Benchmark]:updated - Split на C++,D,C#,Nemerle,Boo,J
От: n0name2  
Дата: 26.09.06 14:33
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>На самом деле (с) GC жрет время не только во время сборки мусора, но и во время выделения памяти. Он рассчитан на работу в многопоточной среде и делает блокировки. Так что если сокнурент не делает блокировок или вообще использует стэк для хранения результатов, то скорость у него будет значительно выше. Но это в таких примитивных тестах. А в реальных условиях все компенсируется.


собственно, за счет TLA удалось улучшить время исполнения с ~500ms до ~400ms. ну, и за счет некоторых других опций (в т.ч. другой стратегии memory compactification).

The allocating Java thread requests a thread-local area (TLA) from the nursery (generational garbage collector) or from the heap (single-generational garbage collector) for allocation of these objects. The TLA is reserved from the heap or the nursery and given to the thread for exclusive use. This allows the thread to allocate small objects in its own TLA without taking any kind of lock. When the TLA gets full the thread simply requests a new TLA.


a thread will try to allocate the object in the currently held TLA. It puts the object at the beginning of the free space in the TLA and moves the free space pointer forward to the end of the object.


плюс ко всему и строки несколько по другому по сравнению с C работают, сама строка это ссылка на массив char [], плюс индекс начала и длинна а не просто ссылка на данные. всякие runtime проверки на индекс в массиве и т.д.
Re[7]: [Benchmark]:updated - Split на C++,D,C#,Nemerle,Boo,J
От: VladD2 Российская Империя www.nemerle.org
Дата: 26.09.06 14:58
Оценка: +1
Здравствуйте, n0name2, Вы писали:

N>Здравствуйте, VladD2, Вы писали:


VD>>На самом деле (с) GC жрет время не только во время сборки мусора, но и во время выделения памяти. Он рассчитан на работу в многопоточной среде и делает блокировки. Так что если сокнурент не делает блокировок или вообще использует стэк для хранения результатов, то скорость у него будет значительно выше. Но это в таких примитивных тестах. А в реальных условиях все компенсируется.


N>собственно, за счет TLA удалось улучшить время исполнения с ~500ms до ~400ms.


Исходников не вижу, так что и сказать ничего не могу. Но TLA (это видимо то что под Виндовс назвается LTS, т.е. локальное хранилище потока), тоже не беслатное. Оно значительно медленее стековой переменной. Так что на С всегда можено сделать чуточку быстрее.

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

С++ в таких тестах перегнать практически невозможно, так как на нем всегда можно скатитсья в С-стиль с оптимизацией каждого бита. Вот только это неоправданно дорого и бессмысленно.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[8]: [Benchmark]:updated - Split на C++,D,C#,Nemerle,Boo,J
От: n0name2  
Дата: 26.09.06 15:18
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Исходников не вижу, так что и сказать ничего не могу. Но TLA (это видимо то что под Виндовс назвается LTS, т.е. локальное хранилище потока), тоже не беслатное. Оно значительно медленее стековой переменной. Так что на С всегда можено сделать чуточку быстрее.


с т.з. исходников использование TLA (в BEA имплементации JVM) или TLAB (так это называется в Sun имплементации JVM) полностью прозрачно. т.е. обчыный new делается не в основном heap а в TLA cache. виндовые TLS требуют явного использования, да и это несколько другая фишка вообще.

насколько я понимаю, Windows TLS http://windowssdk.msdn.microsoft.com/en-us/library/ms686749.aspx это слоты, в которых можно записывать некие значения, а аллоцировать собственно память нужно отдельно.

TLA/TLAB в Java это просто способ аллокации памяти, когда потоку выделяется сразу большой кусок памяти (скажем, 512kb) и после этого он внутри его аллоцирует мелкие объекты вроде строк, массивов и т.п. причем, уже нет необходимости синхронизировать аллокацию с другими потоками.

VD>Вот только кому это нужно. Код подобных оптимизаций неприлично большой.


как раз Sun придерживается той политики что такого рода оптимизации происходят на 100% внутри JVM и программисты об этом думать не должны в момент написания кода. именно поэтому value типы не были реализованы, по мнению Sun это должно (и будет) делаться с помощью escape analysis.
Re[12]: BOOST, .NET, String.Split и производительность…
От: vdimas Россия  
Дата: 26.09.06 18:26
Оценка:
Здравствуйте, VladD2, Вы писали:

FR>>Там на самом деле частично виноват ms только не писатели операционки, а те кто писал рантайм к VC. Поэтому та же первоначальная версия теста откомпилированная со STLPort отрабатывает в полтора раза шустрее.


VD>Извини, а 1.5 раза и 30 раз проигрыша C#-e это сравненимые вещи? А под Линуксом что тормоизило?


VD>А может это и правда заговор? Ну, МС специально подкупили всех писателей библиотек?


Я малость недоумеваю. Вы тут всерьез спорите или как? В С++ строки передаются по значению, то бишь копируются (В C# — по ссылке). Причем, каждый раз создается копия в стандартной куче. Кстати, никто не догадался прогнать этот тест ну хотя бы в однопоточной версии CTR? Или прикрутить минимальный аллокатор для локальной кучи (можно в виндах получить кучу в свое единоличное распоряжение). Там же блокировка происходит каждый раз при обращении к стандартному пулу памяти.

И для таких задач, как правильно заметили, есть const_string. Но опять же, выигрышь будет только со локальным, по отношению к треду, пулом памяти, где брать и возвращать память можно без блокировок.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: BOOST, .NET, String.Split и производительность…
От: vdimas Россия  
Дата: 26.09.06 18:26
Оценка:
Здравствуйте, FR, Вы писали:

А попробуй, плиз, то же самое, но для однопоточной версии рантайма.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[4]: BOOST, .NET, String.Split и производительность…
От: vdimas Россия  
Дата: 26.09.06 18:26
Оценка:
Здравствуйте, eao197, Вы писали:

E>Ну мужики, я ведь только заглянул в split и увидел большое количество копирований предиката. А дальше я не смотрел. Очень вероятно, что сам алгоритм поиска и выделения подстрок грешит таким же избыточным количеством копирований и передачи аргументов по значению.


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

Ну и так же я опять прошу проверить это все на однопоточной версии рантайма.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[8]: BOOST, .NET, String.Split и производительность…
От: vdimas Россия  
Дата: 26.09.06 18:26
Оценка: :)
Здравствуйте, WolfHound, Вы писали:


WH>Вот скажи мне на сколько часто тебе нужны такая лямюбда? Мне нужно как минимум обратится к челену класса, а с этим уже все не так красиво... А если нужно както так Obj.Prop1.Prop2.Prop3 то вобще тушите свет.

WH>Короче для людей которые использовали нормальную лямбду очевидно что boost::lambda непригодно для реальной работы.

Уже обсуждали. Бустовская лямбда хороша для мелких вещей по-месту. Для "крупных" нет проблем нарисовать 2 лишние строки для введения своего функтора:
struct MyFunctor {}
и в нем
void operator()(arg&) {...}
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[9]: BOOST, .NET, String.Split и производительность…
От: WolfHound  
Дата: 26.09.06 18:34
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Уже обсуждали. Бустовская лямбда хороша для мелких вещей по-месту. Для "крупных" нет проблем нарисовать 2 лишние строки для введения своего функтора:

А Obj.Prop1.Prop2.Prop3 это крупный или мелкий случай?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[10]: BOOST, .NET, String.Split и производительность…
От: vdimas Россия  
Дата: 26.09.06 19:43
Оценка: 6 (1)
Здравствуйте, WolfHound, Вы писали:

V>>Уже обсуждали. Бустовская лямбда хороша для мелких вещей по-месту. Для "крупных" нет проблем нарисовать 2 лишние строки для введения своего функтора:

WH>А Obj.Prop1.Prop2.Prop3 это крупный или мелкий случай?

для этого есть var().

In sum, var(x) creates a nullary lambda functor, which stores a reference to the variable x. When the lambda functor is invoked, a reference to x is returned.


юзать так:
var(obj).Prop1.Prop2


Что характерно, так это вот такая особенность:
var(obj.Prop1).Prop2


Понял, в чем прикол?
В общем, var явным образом определяет границы замыкания.
Как такое уточненное замыкание на C# сделать? Я не знаю (кроме как путем превращения мелкого однострочного случая в многострочный путем введения дополнительных "закрываемых" переменных).

А на Nemerle как это сделать элегантно?


-----------
Есть еще constant() для обратного: для насильного вычисления аргумента в момент создания замыкания.

И кстати, lambda-выражения в этой либе можно делать многострочными, с сохранениями промежуточных результатов. Для этого есть еще пара хелперов: var_type и constant_type. (Я что-то не видел примеров здесь на RSDN, наверно мужики не в курсе )
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[3]: [Benchmark] DMD быстрее всех
От: R.K. Украина  
Дата: 26.09.06 19:53
Оценка:
Здравствуйте, cattus, Вы писали:

АХ>>Померил с использованием таймеров (чтобы не учитывать JIT компиляцию)

АХ>>Вот результаты (усреднены по 10 запускам)
АХ>>(Athlon XP 1700+ @ 1.5 GHZ + 512Mb DDR266)
АХ>>:

АХ>>1) DMD — 0.775 сек

АХ>>2) GDC — 0.905 сек
АХ>>3) С#/Nemerle — 1.1 сек
АХ>>4) Python — 3.48 сек
АХ>>5) Python+Psyco — 4.12 (не ускорил!)
АХ>>6) GCC + Boost — 22.5 сек
АХ>>7) MS VC++ + Boost — 35 сек

C>Вот еще одно подтверждение изначальной ущербности теста. Прошу сильно не пинать за код -- я очень долго ничего не писал на Haskell'е.


Достаточно такого:
mapM_ (return.length.words) $ replicate 1000000 "123 345 asdf 23453 asdfas"

На P4-2.8: (0.19 secs, 126628556 bytes), для 10 млн. строк — (1.89 secs, 1281372792 bytes)
You aren't expected to absorb this
Re[4]: BOOST, .NET, String.Split и производительность…
От: FR  
Дата: 26.09.06 20:32
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Здравствуйте, FR, Вы писали:


V>А попробуй, плиз, то же самое, но для однопоточной версии рантайма.


Попробовал почему-то примерно на 10% медленей (VC7.1)
Re[13]: BOOST, .NET, String.Split и производительность…
От: FR  
Дата: 26.09.06 20:32
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Я малость недоумеваю. Вы тут всерьез спорите или как? В С++ строки передаются по значению, то бишь копируются (В C# — по ссылке). Причем, каждый раз создается копия в стандартной куче. Кстати, никто не догадался прогнать этот тест ну хотя бы в однопоточной версии CTR? Или прикрутить минимальный аллокатор для локальной кучи (можно в виндах получить кучу в свое единоличное распоряжение). Там же блокировка происходит каждый раз при обращении к стандартному пулу памяти.


boost::pool прикручивал польза близкая к нулю.
Re[11]: BOOST, .NET, String.Split и производительность…
От: Vermicious Knid  
Дата: 27.09.06 01:57
Оценка: +3
Здравствуйте, vdimas, Вы писали:

WH>>А Obj.Prop1.Prop2.Prop3 это крупный или мелкий случай?

V>для этого есть var().
Я думаю WolfHound совсем не "это" имел в виду. Он говорил о доступе к членам параметра лямбды. А с этим у boost::lambda совсем туго, и иначе и быть не может. Вместо таких безобразий:
_1 ->* &B::foo
bind(&A::data, _1)

На Nemerle можно написать:
_.foo
_.data

Что делать в случае obj.Prop1.Prop2.Prop3 для boost::lambda я затрудняюсь сказать, но что-то мне подсказывает, что ничего хорошего сделать здесь нельзя. А вот на Nemerle это просто:
obj => obj.Prop1.Prop2.Prop3


V>Понял, в чем прикол?

V>В общем, var явным образом определяет границы замыкания.
Скорее var здесь создает иллюзию замыкания. Если значение, на которое этот var ссылается умрет, то думаю все накроется медным тазом. А если подсунуть ему rvalue, то просто не скомпилируется.

V>А на Nemerle как это сделать элегантно?

По-моему на Nemerle лучше "этого" не делать, так как весьма сомнительная это вещь. Ничего кроме усложнения понимания кода она не несет.

Вот скажем слегка измененный пример из документации:
int index = 0; 
for_each(a.end(), a.end(), cout << ++index << ':' << _1 << '\n');

Нормальная лямбда с нормальными замыканиями не напечатала бы ничего. А это недоразумение естественно напечатает 1:. А var это всего лишь костыль для частичного обхода подобных случаев.

Так что не нужно нам таких "элегантных" способов. В Nemerle есть нормальные замыкания, а если понадобится подобная сомнительная вещь, то можно будет сделать — язык вполне позволяет.
Re[11]: BOOST, .NET, String.Split и производительность…
От: night beast СССР  
Дата: 27.09.06 04:24
Оценка: +1 :)
Здравствуйте, vdimas, Вы писали:

V>>>Уже обсуждали. Бустовская лямбда хороша для мелких вещей по-месту. Для "крупных" нет проблем нарисовать 2 лишние строки для введения своего функтора:

WH>>А Obj.Prop1.Prop2.Prop3 это крупный или мелкий случай?

V>для этого есть var().


V>

V>In sum, var(x) creates a nullary lambda functor, which stores a reference to the variable x. When the lambda functor is invoked, a reference to x is returned.


V>юзать так:

V>
V>var(obj).Prop1.Prop2
V>


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

V>Что характерно, так это вот такая особенность:

V>
V>var(obj.Prop1).Prop2
V>


V>Понял, в чем прикол?


я не понял.

V>И кстати, lambda-выражения в этой либе можно делать многострочными, с сохранениями промежуточных результатов. Для этого есть еще пара хелперов: var_type и constant_type. (Я что-то не видел примеров здесь на RSDN, наверно мужики не в курсе )


наверно потому что это выглядит ужасно
Re[5]: [Benchmark]:updated - Split на C++,D,C#,Nemerle,Boo,J
От: JavaBean Украина  
Дата: 27.09.06 07:32
Оценка:
n0name2 wrote:
> JavaBean,
> .countTokens() использовать нельзя т.к. тестируется не подсчет кол-ва
> токенов а именно split на список строк.
Учел твои пожелания
     private static int test() {
         int answer = 0;
         for (int i = 0; i < 1000000; i++) {
             answer+=StringUtils.split("123 345 asdf 23453 asdfas", " 
").length;
         }
         return answer;
     }

Для сплита была взята либа commons lang 2.1

5000000
1139.989
Posted via RSDN NNTP Server 2.0
Re[6]: [Benchmark]:updated - Split на C++,D,C#,Nemerle,Boo,J
От: n0name2  
Дата: 27.09.06 07:51
Оценка:
Здравствуйте, JavaBean, Вы писали:

JB> answer+=StringUtils.split("123 345 asdf 23453 asdfas", "

JB>Для сплита была взята либа commons lang 2.1
JB>5000000
JB>1139.989

это очень медленно. мой рекорд на JRockit с StringTokenizer — 583ms, без него — 392ms
Re[12]: BOOST, .NET, String.Split и производительность…
От: vdimas Россия  
Дата: 27.09.06 10:55
Оценка:
Здравствуйте, night beast, Вы писали:


V>>юзать так:

V>>
V>>var(obj).Prop1.Prop2
V>>


NB>так юзать не получится

NB>по сути var позволяет использовать переменные как лямда-выражение, но не наоборот.

А как-то так:
template<typename T>
var_type<T&>::type lvar(T& obj) { return obj; }

и подставить lvar в приведенный пример? (нет под рукой компилятора, не проверил)
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[13]: BOOST, .NET, String.Split и производительность…
От: night beast СССР  
Дата: 27.09.06 11:51
Оценка: 16 (1)
Здравствуйте, vdimas, Вы писали:

V>>>юзать так:

V>>>
V>>>var(obj).Prop1.Prop2
V>>>


NB>>так юзать не получится

NB>>по сути var позволяет использовать переменные как лямда-выражение, но не наоборот.

V>А как-то так:

V>
V>template<typename T>
V>var_type<T&>::type lvar(T& obj) { return obj; }
V>

V>и подставить lvar в приведенный пример?

дык та же фигня, только в профиль.
var — это функция которая возвращает объект типа lambda_functor< identity<T&> > (var_type<T>::type это тайпдеф этого-же типа).
так-вот, в типе lambda_functor нет никаких переменных Prop1.
сделать то, что ты написал в си нельзя. даже макросами.
извращаются через бинд
bind(&A::Prop1, _1);

такие дела
Re[14]: BOOST, .NET, String.Split и производительность…
От: vdimas Россия  
Дата: 29.09.06 09:50
Оценка: +1
Здравствуйте, WolfHound, Вы писали:

WH>Автор маньякЪ!

WH>Мне лень разбиратся но у меня такое чувство что ты гдето нетак провел декомпозицию.
WH>У меня никогда не возникало жилания сделать такие функторы.

Вообще-то нет. Посмотри, там действительно несколько вложенных if-ов. Имеет ли смысл их декомпозировать? У меня бывают участки подобного if-кода и подлиннее, особенно в той самой логике, котору почему-то называют "бизнес-". (когда позволяют типы аргументов, то это делается через switch-case, но суть не меняется).
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[15]: BOOST, .NET, String.Split и производительность…
От: VladD2 Российская Империя www.nemerle.org
Дата: 29.09.06 17:44
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Вообще-то нет. Посмотри, там действительно несколько вложенных if-ов. Имеет ли смысл их декомпозировать?


Имеет, если в языке есть средства которыми это можно сделать. В С++ с ними туго, вот и получаются монстрики.

Я когда пишу такой код, то чувствую что халтурю. По крайней мере получить удовлетворения от такого я не могу. Удовлетворительный код почему-то всегда получается за одно и хорошо структурированным (с хорошей декомпозицией).
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.