пулл обектов. как оно на самом деле....
От: Shabi  
Дата: 09.08.07 12:04
Оценка: 2 (1)
Недавно тут, обсуждалась тема по поводу имеет ли смысл кэшировать обекты или положиться на VM и пусть они создаються себе...Статьи приводились разные, где выигрышь от повторного использования объектов объявлялсь мифом.
И все как бы с этим согласились, что удивительно. Я тоже было подумал что живу в плену устаревших стериотипов.
Решил проверить как оно на практике.


public class Test 
{
    public static void main(String[] args)
    {
        long t = System.currentTimeMillis();
    
        Rectangle arr = new Rectangle();

        t = System.currentTimeMillis();
        Rectangle c=new Rectangle ();
        
        for (int i = 0; i < 1000000; i++)
        {
            synchronized (c)
            {
                arr = c;//тут иммитируем получение объекта из пула
            }
            
            arr.width =i; // типа используем объект
            
            synchronized (arr)
            {
                c= arr;//тут этот объект возвращаем
            }
        }

        t = System.currentTimeMillis() - t;
        System.out.println(arr + ">>>>>" + t);
        
        System.out.println(c + ">>>>>" + t);

        t = System.currentTimeMillis();
        for (int i = 0; i < 1000000; i++)
        {
            arr = new Rectangle();
            arr.width =i; // типа используем объект
        }


        t = System.currentTimeMillis() - t;
        System.out.println(arr+ "----" + t);
    }
}


такой код выдает


java.awt.Rectangle[x=0,y=0,width=999999,height=0]>>>>>32
java.awt.Rectangle[x=0,y=0,width=999999,height=0]>>>>>32
java.awt.Rectangle[x=0,y=0,width=999999,height=0]----78



те повторное использование объектов в 2 раза быстрее отрабатывает, чем просто создание нового объекта
и это на примере такого примитивного объекта как java.awt.Rectangle.
Напрактике же все ка правило серьезнее. Если вместо java.awt.Rectangle взять Component то будет так


Test$2[,0,0,0x0,invalid]>>>>>31
Test$2[,0,0,0x0,invalid]>>>>>31
Test$3[,0,0,0x0,invalid]----781



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

Перепроверять нужно информацию, даже если она написана не на заборе.
Re: пулл обектов. как оно на самом деле....
От: C0s Россия  
Дата: 09.08.07 12:15
Оценка:
Здравствуйте, Shabi, Вы писали:

S>Решил проверить как оно на практике.


твой пример некорректен, т.к. демонстрирует использование локальных переменных

реальные пулы характерны же тем, что объекты в них переживают конкретный метод и, в конце концов, попадают в область долгоживущих объектов.
далее, при проектированиях пулов встаёт вопрос: является ли количество объектов в пуле фиксированным, или пул будет резиновым?
если пул будет резиновым, то какие-то объекты собирать придётся, и GC будет напрягаться, перепроверяя объекты в области памяти долгоживущих объектов (локальные переменные и локальные объекты, по которым компилятор смог убедиться, что они не выйдут за границы метода, собираются просто)
а если пул нерезиновый, а фиксированный, то тогда он вообще как пул не нужен — достаточно обычных static final-переменных или их более высокопаттерновых аналогов
Re: пулл обектов. как оно на самом деле....
От: sotnik Россия  
Дата: 09.08.07 12:28
Оценка: +1
Здравствуйте, Shabi, Вы писали:

S>Перепроверять нужно информацию, даже если она написана не на заборе.


А где пул собственно? Понятно, что использовать готовый объект быстрее, чем создать новый. Но работу пула это никак не моделирует.
Re: пулл обектов. как оно на самом деле....
От: denis.zhdanov Россия http://denis-zhdanov.blogspot.com/
Дата: 09.08.07 12:41
Оценка: 4 (1) +1
Здравствуйте, Shabi, Вы писали:

S>...


S>Приведенный пример, когда пулл объектов делится меж потоками и соответственно необходимо использовать объекты синхронизации, далеко не самый лучший подход. Я уже давно использую внутрипотоковые пулы и нет никаких проблем с синхронизацией...выигрыш в быстродействии в сотни раз. и где раэрушенные мифы


Как уже сказали, тест некорректен.

Причины:


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


S>Перепроверять нужно информацию, даже если она написана не на заборе.


А вот это уж совсем зря..
http://denis-zhdanov.blogspot.com
Re[2]: пулл обектов. как оно на самом деле....
От: Shabi  
Дата: 09.08.07 13:01
Оценка:
Здравствуйте, C0s, Вы писали:

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


S>>Решил проверить как оно на практике.


C0s>твой пример некорректен, т.к. демонстрирует использование локальных переменных


C0s>реальные пулы характерны же тем, что объекты в них переживают конкретный метод и, в конце концов, попадают в область долгоживущих объектов.


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

C0s>далее, при проектированиях пулов встаёт вопрос: является ли количество объектов в пуле фиксированным, или пул

будет резиновым,

если свободные объекты есть по запросу будет возвращен один из них иначе будет возвращен свежесозданный.

C0s>.... их более высокопаттерновых аналогов


....каков слог


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


Но, повторю, при использовании внутрипотоковых пуллов объектов выигрышь по производительности гораздо серьезнее — в несколько сотен раз.
Re[3]: пулл обектов. как оно на самом деле....
От: denis.zhdanov Россия http://denis-zhdanov.blogspot.com/
Дата: 09.08.07 13:22
Оценка:
Здравствуйте, Shabi, Вы писали:

S>конкретно в этом примере без повторного использования объектов напрягается VM, и безовсяких условий. сделать с этим ничего нельзя.


Конкретно в этом примере JVM вообще не напрягается. См. мой пост
Автор: denis.zhdanov
Дата: 09.08.07
про отпимизации компилятора.


S>повторное использование объектов приводит к их попаданию в коллекцию долгоживущих, что при некоторых обстаятельствах может привести напряжению в работе GC. как с этим бороться понятно. нужно стараться по возможности следить и возвращвть объекты после использования.


Реиспользование объектов перпендикулярно их перемещнию по heap generations. На это влият только статус объекта во время garbage collection (strongly/softly/weakly/phantomly reachable/unreachable). GC будет напрягаться от любой политики неправильного heap management, т.е. если ты задашь маленький edem и будешь клепать короткоживущие объекты без передыха, хорошего ничего не выйдет.


S>Но, повторю, при использовании внутрипотоковых пуллов объектов выигрышь по производительности гораздо серьезнее — в несколько сотен раз.


Внутрипотоковый пул называется ThreadLocal и он как-то не особо связан с разговором о разнице в производительности между lock contended pool и new object allocation.
http://denis-zhdanov.blogspot.com
Re[2]: пулл обектов. как оно на самом деле....
От: Shabi  
Дата: 09.08.07 14:34
Оценка:
Здравствуйте, denis.zhdanov, Вы писали:

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


S>>...


S>>Приведенный пример, когда пулл объектов делится меж потоками и соответственно необходимо использовать объекты синхронизации, далеко не самый лучший подход. Я уже давно использую внутрипотоковые пулы и нет никаких проблем с синхронизацией...выигрыш в быстродействии в сотни раз. и где раэрушенные мифы


DZ>Как уже сказали, тест некорректен.


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


DZ>Причины:



DZ>
  • основные тормоза пулов заключаются в lock contention. У тебя же тут один поток всего.

    вот это аргумент пробуем делать многопоточно

    import java.awt.*;
    
    public class Test
    {
        private static class MyObject extends Rectangle
        {
            public MyObject next;
            public int field;
    
        }
    
        private static MyObject pool = null;
    
        public static synchronized MyObject getMyObject()
        {
            MyObject ret = pool;
            
            if (pool == null) ret = new MyObject();
            else pool = ret.next;
    
            ret.next = ret;
            return ret;
        }
    
        public static synchronized void putMyObject(MyObject myObject)
        {
            if (myObject.next == myObject)
            {
                myObject.next = pool;
                pool = myObject;
            }
            //else или кидаем ошибку или игнорируем
        }
    
    
        static void test1()
        {
            long t = System.currentTimeMillis();
    
            t = System.currentTimeMillis();
    
            for (int i = 0; i < 1000000; i++)
            {
                MyObject obj = getMyObject();
    
                obj.field = i; // типа используем объект
    
                putMyObject(obj);
            }
    
            t = System.currentTimeMillis() - t;
            System.out.println("Reuse " + t);
        }
    
        static void test2()
        {
            long t = System.currentTimeMillis();
    
            t = System.currentTimeMillis();
            for (int i = 0; i < 1000000; i++)
            {
                MyObject obj = new MyObject();
    
                obj.field = i; // типа используем объект
            }
    
            t = System.currentTimeMillis() - t;
            System.out.println("New" + t);
        }
    
        public static void main(String[] args)
        {
            new Thread()
            {
                public void run()
                {
                    test1();
                }
            }.start();
            new Thread()
            {
                public void run()
                {
                    test1();
                }
            }.start();
            new Thread()
            {
                public void run()
                {
                    test1();
                }
            }.start();
            new Thread()
            {
                public void run()
                {
                    test1();
                }
            }.start();
    
            ///===================================================
    
            new Thread()
            {
                public void run()
                {
                    test2();
                }
            }.start();
            new Thread()
            {
                public void run()
                {
                    test2();
                }
            }.start();
            new Thread()
            {
                public void run()
                {
                    test2();
                }
            }.start();
            new Thread()
            {
                public void run()
                {
                    test2();
                }
            }.start();
        }
    }


    получаем в случии примитивного пулла повторного использования объектов весьма незначительный выигрыш

    Reuse 1875
    Reuse 2094
    Reuse 2047
    Reuse 1969
    New2234
    New2281
    New2297
    New2297

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

    Лично я практикую потоко-контекстные (внутрипотоковые) пуллы типа такого

    import java.awt.*;
    
    public class Test
    {
        private static class MyObject extends Component
        {
            public MyObject next;
            public int field;
        }
    
        public static class Pool
        {
            private static Pool pool;
            private Pool next;
            private MyObject myObject;
    
            public static synchronized Pool getPool()
            {
                Pool ret = pool;
                if (ret == null) ret = new Pool();
                else pool = ret.next;
                
                ret.next = ret;
                return ret;
            }
    
            public static synchronized void putPool(Pool p)
            {
                if (p.next == p)
                {
                    p.next = pool;
                    pool = p;
                }
            }
    
            public MyObject getMyObject()
            {
                MyObject ret = myObject;
    
                if (ret == null) ret = new MyObject();
                else myObject = ret.next;
    
                ret.next = ret;
    
                return ret;
            }
    
            public void putMyObject(MyObject obj)
            {
                if (obj.next == obj)
                {
                    obj.next = myObject;
                    myObject = obj;
                }
                //else или кидаем ошибку или игнорируем
            }
        }
    
    
        static void test1(Pool pool)
        {
            long t = System.currentTimeMillis();
    
            t = System.currentTimeMillis();
    
            for (int i = 0; i < 1000000; i++)
            {
                MyObject obj = pool.getMyObject();
    
                obj.field = i; // типа используем объект
    
                pool.putMyObject(obj);
            }
    
            t = System.currentTimeMillis() - t;
            System.out.println("Reuse " + t);
        }
    
        static void test2()
        {
            long t = System.currentTimeMillis();
    
            t = System.currentTimeMillis();
            for (int i = 0; i < 1000000; i++)
            {
                MyObject obj = new MyObject();
    
                obj.field = i; // типа используем объект
            }
    
            t = System.currentTimeMillis() - t;
            System.out.println("new" + t);
        }
    
        public static void main(String[] args)
        {
            new Thread()
            {
                public void run()
                {
                    Pool pool = Pool.getPool();
                    test1(pool);
                    Pool.putPool(pool);
                }
            }.start();
            new Thread()
            {
                public void run()
                {
                    Pool pool = Pool.getPool();
                    test1(pool);
                    Pool.putPool(pool);
                }
            }.start();
            new Thread()
            {
                public void run()
                {
                    Pool pool = Pool.getPool();
                    test1(pool);
                    Pool.putPool(pool);
                }
            }.start();
            new Thread()
            {
                public void run()
                {
                    Pool pool = Pool.getPool();
                    test1(pool);
                    Pool.putPool(pool);
                }
            }.start();
    
            ///===================================================
    
            new Thread()
            {
                public void run()
                {
                    test2();
                }
            }.start();
            new Thread()
            {
                public void run()
                {
                    test2();
                }
            }.start();
            new Thread()
            {
                public void run()
                {
                    test2();
                }
            }.start();
            new Thread()
            {
                public void run()
                {
                    test2();
                }
            }.start();
        }
    }


    на примитивных обектах получаем выигрышь примерно в 2 раза при этом код достаточно хорошо ведет себя при любом количестве потоков.

    Reuse 203
    Reuse 250
    Reuse 359
    Reuse 343
    new547
    new594
    new610
    new625

    Чем более сложные объекты тем выигрышь более очевиден. Например Component
    Reuse 125
    Reuse 156
    Reuse 218
    Reuse 203
    new3000
    new3203
    new3219
    new3312


    DZ>Соотв-но все приведенные цифры идут отдыхать;


    Денис, я ТЕБЯ уважаю. Хотя я тебя не знаю. Несомненно, ты очень хороший специалист и тебя ценят и любят в твоем коллективе так, что твое мнение является самым авторитетным. Но тут мы плохо знаем друг друга. Поэтому я буду приветствовать если ты будешь отвечать более аргументированно, с цифрами.
    Мне правда хочется разобраться, а не мерица длинно и толщиной..



    S>>Перепроверять нужно информацию, даже если она написана не на заборе.


    DZ>А вот это уж совсем зря..


    Практика она ж ведь того...критерий истинны.
  • Re[4]: пулл обектов. как оно на самом деле....
    От: Shabi  
    Дата: 09.08.07 14:47
    Оценка:
    Здравствуйте, denis.zhdanov, Вы писали:

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


    S>>конкретно в этом примере без повторного использования объектов напрягается VM, и безовсяких условий. сделать с этим ничего нельзя.


    DZ>Конкретно в этом примере JVM вообще не напрягается. См. мой пост
    Автор: denis.zhdanov
    Дата: 09.08.07
    про отпимизации компилятора.


    Денис за ссылки спасибо, но я их уже читал.

    S>>Но, повторю, при использовании внутрипотоковых пуллов объектов выигрышь по производительности гораздо серьезнее — в несколько сотен раз.


    DZ>Внутрипотоковый пул называется ThreadLocal и он как-то не особо связан с разговором о разнице в производительности между lock contended pool и new object allocation.


    У нас тут терминологическое разночтение, говоря о внутрипотоковых пуллах я имел ввиду совершенно другое. Будем считать, что это я коряво выражаюсь.
    Re[3]: пулл обектов. как оно на самом деле....
    От: C0s Россия  
    Дата: 09.08.07 15:14
    Оценка: +1
    Здравствуйте, Shabi, Вы писали:

    S>Поэтому я буду приветствовать если ты будешь отвечать более аргументированно, с цифрами.

    S>Мне правда хочется разобраться, а не мерица длинно и толщиной..

    боюсь, мы до цифр пока не дошли
    в твоём примере присутствует недостаток, который, может быть и не заметен в мире awt-программ, но совершенно неприемлем в мире серверых долгоживущих процессов, а именно, отсутствие освобождения пулов

    т.е. речь о том, что я уже написал выше — если пул резиновый, то надо предусматривать освобожение объектов, например, пользоваться Soft/WeakReferences. иначе, это просто можно трактовать как источник утечки памяти.

    далее, нам нужна защита от дурака: мы же в общем случае можем захотеть туда совать сложные объекты, а программист Петя додумается в сложный объект x5 засунуть ссылку на охренно-большой, но уже ненужный объект selectResult. т.е. в операции putObjectToPool надо обнулять ссылки, иначе проблема утечек памяти будет ещё острее

    так что настоящий пул будет вынужден делать несколько дополнительных операций
    цифрами любишь заниматься ты, так что предоставляю тебе возможность померить, как там будет с производительностью при вызове метода cleanupMyBigStupidObject, которому потребуется обнулить штук 15 ссылок операцией присваивания, а также удастся ли сходу написать правильные манипуляции с Soft/Weak-ссылками

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

    ps. кстати, внутрипотоковость, проще реализуется через ThreadLocal и без синхронизации, как у тебя
    Re[2]: пулл обектов. как оно на самом деле....
    От: rsn81 Россия http://rsn81.wordpress.com
    Дата: 09.08.07 15:20
    Оценка: +1
    Здравствуйте, denis.zhdanov, Вы писали:

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

    Именно.
    Кстати, эти две статьи есть и в переводе:
    Теория и практика Java: Анатомия некорректных микротестов оценки производительности
    Теория и практика Java: Динамическая компиляция и измерение производительности

    S>Перепроверять нужно информацию, даже если она написана не на заборе.

    Такая проверка, которую вы привели, ничем не лучше надписи на заборе, уж извините.
    Re[4]: пулл обектов. как оно на самом деле....
    От: Shabi  
    Дата: 09.08.07 15:32
    Оценка:
    Здравствуйте, C0s, Вы писали:


    C0s>боюсь, мы до цифр пока не дошли

    C0s>в твоём примере присутствует недостаток, который, может быть и не заметен в мире awt-программ, но совершенно неприемлем в мире серверых долгоживущих процессов, а именно, отсутствие освобождения пулов

    C0s>т.е. речь о том, что я уже написал выше — если пул резиновый, то надо предусматривать освобожение объектов, например, пользоваться Soft/WeakReferences. иначе, это просто можно трактовать как источник утечки памяти.


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

    C0s>далее, нам нужна защита от дурака:


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


    C0s>так что настоящий пул будет вынужден делать несколько дополнительных операций


    а может и нет. обсудили.

    C0s>ps. кстати, внутрипотоковость, проще реализуется через ThreadLocal и без синхронизации, как у тебя


    в итернете можно много найти разного на тему ThreadLocal performance и как не странно я даже согласен с написанным. Ибо проверил лично. Не поленись загляни внутрь кошмарика под названием ThreadLocal.
    Re[3]: пулл обектов. как оно на самом деле....
    От: Shabi  
    Дата: 09.08.07 15:43
    Оценка:
    Здравствуйте, rsn81, Вы писали:

    R>Здравствуйте, denis.zhdanov, Вы писали:


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

    R>Именно.
    R>Кстати, эти две статьи есть и в переводе:
    R>Теория и практика Java: Анатомия некорректных микротестов оценки производительности
    R>Теория и практика Java: Динамическая компиляция и измерение производительности

    S>>Перепроверять нужно информацию, даже если она написана не на заборе.

    R>Такая проверка, которую вы привели, ничем не лучше надписи на заборе, уж извините.

    согласен, это забор на противоположной стороне...так я не предлагаю мне ВЕРИТЬ. давайте разберемся. я правда стараюсь докопаться до сути, пишу тесты, проверяю. Тем более это не так уж и сложно и доступно. У меня нет какого либо предопределенного ответа. Мне нужна истинна. Возможно что для кого-то истинной становится все, что напечатано где-то...

    Лично мне не важно окажусь прав я или нет,просто эта тема опять поднялась, она меня волнует, и я откликнулся.
    Мне нужно докопаться до дна и больше не возвращаться к ней. примерно так
    Re[5]: пулл обектов. как оно на самом деле....
    От: C0s Россия  
    Дата: 09.08.07 15:47
    Оценка: 1 (1)
    Здравствуйте, Shabi, Вы писали:

    S>как знать, как знать. а вдруг вся эта гирлянда ссылок на объекты и есть та самая ценность, тот самы смысл ради которого объект предпочтительней бережно возвращать в пулл, бо создание не чтоподобного с нуля — затратно.


    пример?
    обычно объекты в пуле равнозначны с точки зрения того, кому нужен новый объект
    мне очень сомнительно, что задача получения "наиболее подходящего объекта" из пула вместо первого попавшегося только из-за того, что в нём сохранились суперценные ссылки имеет смысл

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


    если судить по этой дискуссии, то единственная проблема — это энтузиасты преждевременных оптимизаций

    C0s>>так что настоящий пул будет вынужден делать несколько дополнительных операций


    S>а может и нет. обсудили.


    т.е. мы можем плавно переходить к обсуждению вопросов поддержки сотни узкоспециальных пулов, понатыканных по всей программе?

    S>в итернете можно много найти разного на тему ThreadLocal performance и как не странно я даже согласен с написанным. Ибо проверил лично. Не поленись загляни внутрь кошмарика под названием ThreadLocal.


    доп. правило: "не оптимизируйте, даже если очень хочется"
    Re[3]: пулл обектов. как оно на самом деле....
    От: denis.zhdanov Россия http://denis-zhdanov.blogspot.com/
    Дата: 09.08.07 15:50
    Оценка:
    Здравствуйте, Shabi, Вы писали:

    S>вот с этого места хотелось бы увидеть хотябы намёк на тест который с Вашей , Денис, точки зрения является корректым тест.

    S>мне действительно хочется разобраться.

    Если хочется разобраться, почему ты забиваешь на упомнинания о том, что не учитывается jit, gc & dead code elimination?
    Также тест неправильный еще и из-за того, что потоки, выполняющие test1() стартуют раньше потоков, выполняющих test2() ==> вторая группа работает в режиме более жесткой конкуренции за системные ресурсы. Плюс из-за того, что как ни крути, в итоге gc скажет stop-the-world, а он скажет во время работы второй группы, первая также затормозится).


    DZ>>Причины:


    DZ>>
  • основные тормоза пулов заключаются в lock contention. У тебя же тут один поток всего.

    S>вот это аргумент пробуем делать многопоточно

    S>...

    Непонятно, как ты запускаешь вообще. У меня выдало (с ключом -server, с дефолтными настройками gc)

    New63
    New109
    New141
    New156
    New156
    Reuse 43609
    Reuse 43609
    Reuse 43641
    Reuse 43672
    Reuse 43672


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


    package com;
    
    import java.io.*;
    import java.util.regex.Pattern;
    import java.util.regex.Matcher;
    import java.util.List;
    import java.util.Collections;
    import java.util.LinkedList;
    import java.util.ArrayList;
    import java.awt.*;
    
    import org.springframework.remoting.rmi.RmiServiceExporter;
    import weblogic.jms.extensions.WLSession;
    import weblogic.jms.extensions.WLQueueSession;
    
    
    /**
     * @author Denis Zhdanov
     * @since 18.05.2007
     */
    public class BBB {
    
        private static class MyObject extends Rectangle {
            public MyObject next;
            public int field;
        }
    
    
        private static MyObject pool = null;
        private static List<MyObject> pool2 = new ArrayList<MyObject>();
    
        public static synchronized MyObject getMyObject() {
            MyObject ret = pool;
    
            if (pool == null) {
                ret = new MyObject();
            } else {
                pool = ret.next;
            }
    
            ret.next = ret;
            return ret;
        }
    
        public static synchronized void putMyObject(MyObject myObject) {
            if (myObject.next == myObject) {
                myObject.next = pool;
                pool = myObject;
            }
            //else или кидаем ошибку или игнорируем
        }
    
    
        static void test1() {
            long t = System.currentTimeMillis();
    
            for (int i = 0; i < 1000000; i++) {
                MyObject obj = getMyObject();
    
                obj.field = i; // типа используем объект
    
                putMyObject(obj);
            }
    
            t = System.currentTimeMillis() - t;
            System.out.println("Reuse " + t);
        }
    
        static void test2() {
            long t = System.currentTimeMillis();
    
            for (int i = 0; i < 1000000; i++) {
                MyObject obj = null;
                synchronized (BBB.class) {
                    if (pool2.size() != 0) {
                        obj = pool2.remove(pool2.size() - 1);
                    }
                }
                if (obj == null) {
                    obj = new MyObject();
                }
                obj.field = i; // типа используем объект
                synchronized (BBB.class) {
                    pool2.add(obj);
                }
            }
    
            t = System.currentTimeMillis() - t;
            System.out.println("List" + t);
        }
    
        public static void main(String[] args) throws InterruptedException {
            List<Thread> threads1 = new ArrayList<Thread>();
            List<Thread> threads2 = new ArrayList<Thread>();
            for (int i = 0; i < 5; ++i) {
                threads1.add(new Thread() {
                    public void run() {
                        test1();
                    }
                });
                threads2.add(new Thread() {
                    public void run() {
                        test2();
                    }
                });
            }
    
            for (Thread thread : threads1) {
                thread.start();
            }
    
            for (Thread thread : threads1) {
                thread.join();
            }
    
            for (Thread thread : threads2) {
                thread.start();
            }
        }
    }


    Результат:
    Reuse 38390
    Reuse 38406
    Reuse 38656
    Reuse 38656
    Reuse 38656
    List34672
    List37984
    List37984
    List37984
    List38016



    S>получаем в случии примитивного пулла повторного использования объектов весьма незначительный выигрыш


    Слушай, в тех же статейках, на которые я давал ссылки, а ты говорил, что читал, было написано, что во времена java1, java2 действительно пулинг был производительнее new allocation. Признавайся, ты какую джаву используешь?


    S>который вероятно может сойти на нет в случаи большого количества потоков. Но, как я уже писал выше

    S>подобные пулы — вчерашний день.

    S>Лично я практикую потоко-контекстные (внутрипотоковые) пуллы типа такого

    S>...

    Извини, непонятно, что ты этим хотел показать. Что thread-local call быстрее создания объекта или lock contended pool call? Так с этим никто не спорит. Разговор идет о том, что эффективнее — использовать из любой части программы/любого потока contended pool или делать new и давать overhead на gc. По моему четкому ощущению ты выступаешь за первый вариант.


    S>Денис, я ТЕБЯ уважаю. Хотя я тебя не знаю. Несомненно, ты очень хороший специалист и тебя ценят и любят в твоем коллективе так, что твое мнение является самым авторитетным. Но тут мы плохо знаем друг друга. Поэтому я буду приветствовать если ты будешь отвечать более аргументированно, с цифрами.

    S>Мне правда хочется разобраться, а не мерица длинно и толщиной..

    Спасибо на добром слове
    Так если тебе хочется разобраться, почему ты выцепил только один аргумент из того, что я привел? Плюс еще показал какие-то невероятные цифры. В приведенных статьях очень неплохо расписаны многие подводные камни, которые возникают при написании тестов. Ты их просто напросто игнорируешь, а говоришь, что все прочитал.
  • http://denis-zhdanov.blogspot.com
    Re[4]: пулл обектов. как оно на самом деле....
    От: C0s Россия  
    Дата: 09.08.07 15:55
    Оценка: 9 (3) +1
    Здравствуйте, Shabi, Вы писали:

    S>Лично мне не важно окажусь прав я или нет,просто эта тема опять поднялась, она меня волнует, и я откликнулся.

    S>Мне нужно докопаться до дна и больше не возвращаться к ней. примерно так

    всё-таки, как мне кажется, это вопрос философский, а не измерительный

    1) если проект простой, то там вообще редко цифры важны, заказчик удовлетворяется тем, что всё работает

    2) если проект сложный, то на первое место выходит правильность кода и лёгкость его сопровождения. грубо говоря, чем меньше и проще написано, тем проекту в перспективе лучше.
    для этого не надо писать своих пулов, не надо прикручивать чужие пулы, не надо thread local, достаточно простых и понятных локальных переменных
    только если заказчика не устроит производительность, и при профайлинге какого-то конкретного участка на хардвере заказчика выяснится, что можно этот участок улучшить введением пула (причём, перед этим надо подумать, может static подойдёт и/или thread local), то только тогда его будет иметь смысл вводить в программу

    а абстрактно разбираться, какие тестовые методы выполняются быстрее на твоём компьютере не так уж и интересно
    Re[4]: пулл обектов. как оно на самом деле....
    От: Shabi  
    Дата: 10.08.07 03:32
    Оценка: -3
    Здравствуйте, denis.zhdanov, Вы писали:

    DZ>Также тест неправильный еще и из-за того, что потоки, выполняющие test1() стартуют раньше потоков, выполняющих test2() ==> вторая группа работает в режиме более жесткой конкуренции за системные ресурсы. Плюс из-за того, что как ни крути, в итоге gc скажет stop-the-world, а он скажет во время работы второй группы, первая также затормозится).


    это замечание Вас дескридитирует, как профессионала. Нет там понятия раньше позже.

    DZ>Непонятно, как ты запускаешь вообще. У меня выдало (с ключом -server, с дефолтными настройками gc)


    DZ>
    DZ>New63
    DZ>New109
    DZ>New141
    DZ>New156
    DZ>New156
    DZ>Reuse 43609
    DZ>Reuse 43609
    DZ>Reuse 43641
    DZ>Reuse 43672
    DZ>Reuse 43672
    DZ>


    это очень странно, у меня jdk1.6.0 с опцией -server
    Reuse 141
    Reuse 172
    Reuse 265
    Reuse 266
    new2235
    new2313
    new2360
    new2375


    jdk1.5.0_12 с опцией -server
    Reuse 109
    Reuse 125
    Reuse 141
    Reuse 172
    new2187
    new2219
    new2266
    new2313






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



    DZ>
    DZ>package com;
    
    DZ>public class BBB {
    
    DZ>    private static List<MyObject> pool2 = new ArrayList<MyObject>();
    DZ>


    DZ>Результат:

    DZ>
    Reuse 38390
    DZ>Reuse 38406
    DZ>Reuse 38656
    DZ>Reuse 38656
    DZ>Reuse 38656
    DZ>List34672
    DZ>List37984
    DZ>List37984
    DZ>List37984
    DZ>List38016
    DZ>


    фактически тут ты мерил скорость обращения к ArrayList

    S>>Лично я практикую потоко-контекстные (внутрипотоковые) пуллы типа такого

    S>>...

    DZ>Извини, непонятно, что ты этим хотел показать. Что thread-local call быстрее создания объекта или lock contended pool call? Так с этим никто не спорит. Разговор идет о том, что эффективнее — использовать из любой части программы/любого потока contended pool или делать new и давать overhead на gc. По моему четкому ощущению ты выступаешь за первый вариант.


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

    S>>Денис, я ТЕБЯ уважаю. Хотя я тебя не знаю. Несомненно, ты очень хороший специалист и тебя ценят и любят в твоем коллективе так, что твое мнение является самым авторитетным. Но тут мы плохо знаем друг друга. Поэтому я буду приветствовать если ты будешь отвечать более аргументированно, с цифрами.

    S>>Мне правда хочется разобраться, а не мерица длинно и толщиной..

    DZ>Спасибо на добром слове

    DZ>Так если тебе хочется разобраться, почему ты выцепил только один аргумент из того, что я привел? Плюс еще показал какие-то невероятные цифры. В приведенных статьях очень неплохо расписаны многие подводные камни, которые возникают при написании тестов. Ты их просто напросто игнорируешь, а говоришь, что все прочитал.

    а в этих статьях написано, если кратко, типа мы и сами хило представляем, как это сработает в конкретном случае.

    и причем тут подводные камни при написании тестов?

    Представь что тесты для тебя это как раз именно то, что должно работать быстро.Что Это и есть та самая софтина которую ты пишешь. Тесты не с потолка валятся, чаще всего это концентрат, скелет, костяк архитектуры некоторых кусков реальных проектов очищенный от ненужного, не существенного кода. Это давно известно, что компилятор может вытворять, естественно, при написании тестов это держится в голове.
    Re[5]: пулл обектов. как оно на самом деле....
    От: Kuzz Россия  
    Дата: 11.08.07 06:07
    Оценка:
    Здравствуйте, Shabi, Вы писали:

    S> Нет там понятия раньше позже.

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

    S>я посередине, я утверждаю, что грамотное использование пуллов дает выигрыш в производительности.(точка)

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

    И вообще, то, что сейчас работает быстрее, даже на последней версии JVM, не факт, что будем таковым в будущем. Все, что касается производительности должно интересовать разработчика только в последнюю очередь, и то, если она не удовлетворит заказчика на его железе, как вам и сказал cOs.
    Actions speak louder than words
    Re[6]: пулл обектов. как оно на самом деле....
    От: Shabi  
    Дата: 11.08.07 12:01
    Оценка:
    Здравствуйте, Kuzz, Вы писали:

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


    S>> Нет там понятия раньше позже.

    K>Если вы хотите, чтобы у вас не было понятия раньше позже -- используйте например, барьеры, чтобы все потоки начали выполнение одновременно (ну, или почти одновременно ). А то один поток может вообще завершится, пока другой не начнется.

    я, признаюсь иногда случается тупым бываю... вот сейчас например, я правда не понимаю о чем речь? (я добросовестно перечитал несколько раз данную подветку).


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


    1) ...еще раз. я обсуждал в контексте того, что все дружно согласились что пулл объектов -это плохо. мой ответ содержит о том что все далеко не так однозначно.(вот тут точка)

    2)ответьте проблеммы производительностьи каких платформ/языков в интернете обсуждают чаще всего неужели С++
    или у меня неправильный интернет?

    3)так и осталось не понятным конкретно по тестам есть что сказать?(не торопитесь отвечать в прежнем стиле, пункт 1 важен)
    Re[7]: пулл обектов. как оно на самом деле....
    От: mikkri Великобритания  
    Дата: 12.08.07 12:48
    Оценка:
    Здравствуйте, Shabi, Вы писали:

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


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


    S>>> Нет там понятия раньше позже.

    K>>Если вы хотите, чтобы у вас не было понятия раньше позже -- используйте например, барьеры, чтобы все потоки начали выполнение одновременно (ну, или почти одновременно ). А то один поток может вообще завершится, пока другой не начнется.

    S> я, признаюсь иногда случается тупым бываю... вот сейчас например, я правда не понимаю о чем речь? (я добросовестно перечитал несколько раз данную подветку).


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

    Чтобы ситуацию приблизить к жизненной нужно использовать барьер, т.е. механизм, который не даст вашим потокам исполнять "бизнес-логику" до того, как все потоки дойдут до барьера. В такой ситуации потоки начнут исполнять "бизнес-логику" почти одновременно — с минимально возможной задержкой.
    Re[5]: пулл обектов. как оно на самом деле....
    От: mikkri Великобритания  
    Дата: 12.08.07 12:51
    Оценка:
    Здравствуйте, C0s, Вы писали:

    C0s>а абстрактно разбираться, какие тестовые методы выполняются быстрее на твоём компьютере не так уж и интересно


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

    Кстаты, ты под Solaris, Linux или Windows тест гоняешь? Какая разница между ОС по результатам твоего теста?
    Re[8]: пулл обектов. как оно на самом деле....
    От: Shabi  
    Дата: 13.08.07 07:31
    Оценка:
    Здравствуйте, mikkri, Вы писали:

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

    увидив в моем коде вот это


    public static void main(String[] args)
        {
            new Thread()
            {
                public void run()
                {
                    test1();
                }
            }.start();
            new Thread()
            {
                public void run()
                {
                    test1();
                }
            }.start();
            new Thread()
            {
                public void run()
                {
                    test1();
                }
            }.start();
            new Thread()
            {
                public void run()
                {
                    test1();
                }
            }.start();
    
            ///===================================================
    
            new Thread()
            {
                public void run()
                {
                    test2();
                }
            }.start();
            new Thread()
            {
                public void run()
                {
                    test2();
                }
            }.start();
            new Thread()
            {
                public void run()
                {
                    test2();
                }
            }.start();
            new Thread()
            {
                public void run()
                {
                    test2();
                }
            }.start();
        }



    цитирую — denis.zhdanov пишет

    Также тест неправильный еще и из-за того, что потоки, выполняющие test1() стартуют раньше потоков, выполняющих test2() ==> вторая группа работает в режиме более жесткой конкуренции за системные ресурсы.


    на что я отвечаю

    это замечание Вас дескридитирует, как профессионала. Нет там понятия раньше позже.


    вы со мной согласны?


    на что я получаю ответ

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


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

    M>Речь о том, что когда вы последовательно запускаете потоки, то они стартуют не одновременно, как нужно для теста, а последовательно. И из-за задержек, связанных с созданием нового потока, времена запуска потоков будут сильно разниться.


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


    кто Вам сказал что для теста нужно чтобы потоки стартовали одновременно? и откуда информация про минимально возможную задержку?

    я в недоумении. там все отданно на откуп шедулерру потоков. барьер вам только гарантирует только понятие "не раньше чем" и все.
    Re[5]: [от модератора]
    От: Blazkowicz Россия  
    Дата: 13.08.07 10:58
    Оценка:
    Здравствуйте, Shabi, Вы писали:

    S>это замечание Вас дескридитирует, как профессионала. Нет там понятия раньше позже.


    Прошу обратить Ваше внимание, что процитированный пассаж является грубым нарушением Обязательных правил сайта. Подобное поведение в дальнейшем может повлечь за собой ограничения ваших свобод на rsdn.ru
    Re[9]: пулл обектов. как оно на самом деле....
    От: Blazkowicz Россия  
    Дата: 13.08.07 11:33
    Оценка:
    Здравствуйте, Shabi, Вы писали:

    S> я в недоумении. там все отданно на откуп шедулерру потоков. барьер вам только гарантирует только понятие "не раньше чем" и все.


    Правильно, что в свою очередь очень здорово сокращает время между реальными запусками методов.
    Может это... зачем трепаться по пусту. Запустим, да проверим. Уже на 10 потоках разница хорошо видна не вооруженным глазом.

    import java.util.concurrent.CyclicBarrier;
    import java.util.concurrent.Callable;
    import java.util.concurrent.Executors;
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * This class represents...
     */
    public class Test
    {
        private static final int PARTIES = 10;
    
        private static void test(long start)
        {
            System.out.println(Thread.currentThread().getName() + "  " + (System.nanoTime() - start));
        }
    
        public static void main(String[] args) throws InterruptedException
        {
    //        test1();
    //        test2();
            test3();
        }
    
        private static void test2() throws InterruptedException
        {
            final CyclicBarrier barrier = new CyclicBarrier(PARTIES);
            List<Callable<Object>> tasks = new ArrayList<Callable<Object>>();
            final long start = System.nanoTime();
            for (int i = 0; i < PARTIES; i++)
            tasks.add(new Callable<Object>()
            {
                public Object call() throws Exception
                {
                    barrier.await();
                    test(start);
                    return null;
                }
            });
            Executors.newScheduledThreadPool(tasks.size()).invokeAll(tasks);
        }
    
    
        private static void test1()
        {
            final long start = System.nanoTime();
            for (int i = 0; i < PARTIES; i++)
            {
                new Thread(){
                    public void run()
                    {
                        test(start);
                    }
                }.start();
            }
        }
        private static void test3()
        {
            final long start = System.nanoTime();
                new Thread(){
                    public void run()
                    {
                        test(start);
                    }
                }.start();
                new Thread(){
                    public void run()
                    {
                        test(start);
                    }
                }.start();
                new Thread(){
                    public void run()
                    {
                        test(start);
                    }
                }.start();
                new Thread(){
                    public void run()
                    {
                        test(start);
                    }
                }.start();
                new Thread(){
                    public void run()
                    {
                        test(start);
                    }
                }.start();
                new Thread(){
                    public void run()
                    {
                        test(start);
                    }
                }.start();
                new Thread(){
                    public void run()
                    {
                        test(start);
                    }
                }.start();
                new Thread(){
                    public void run()
                    {
                        test(start);
                    }
                }.start();
                new Thread(){
                    public void run()
                    {
                        test(start);
                    }
                }.start();
                new Thread(){
                    public void run()
                    {
                        test(start);
                    }
                }.start();
            }
    
    }
    Re[10]: пулл обектов. как оно на самом деле....
    От: Shabi  
    Дата: 14.08.07 05:42
    Оценка:
    Здравствуйте, Blazkowicz, Вы писали:


    B>
    B>import java.util.concurrent.CyclicBarrier;
    B>import java.util.concurrent.Callable;
    B>import java.util.concurrent.Executors;
    B>import java.util.ArrayList;
    B>import java.util.List;
    
    B>/**
    B> * This class represents...
    B> */
    B>public class Test
    B>{
    ............
    
    B>    private static void test2() throws InterruptedException
    B>    {
    B>        final CyclicBarrier barrier = new CyclicBarrier(PARTIES);
    B>        List<Callable<Object>> tasks = new ArrayList<Callable<Object>>();
    B>        final long start = System.nanoTime();
    B>        for (int i = 0; i < PARTIES; i++)
    B>        tasks.add(new Callable<Object>()
    B>        {
    B>            public Object call() throws Exception
    B>            {
    B>                barrier.await();
    B>                test(start);
    B>                return null;
    B>            }
    B>        });
    B>        Executors.newScheduledThreadPool(tasks.size()).invokeAll(tasks);
    B>    }
    
    B>            new Thread(){
    B>                public void run()
    B>                {
    B>                    test(start);
    B>                }
    B>            }.start();
    B>        }
    
    B>}
    B>


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

    В моем исполнении все тоже самое будет выглядить так...


    public class test2
    {
        static long min_time = Long.MAX_VALUE, max_time = Long.MIN_VALUE;
        static String min_name = "", max_name = "";
    
        static final Object lock1 = new Object();
    
        static int threads_count = 10, current_count = 0;
    
        public static void test()
        {
            long t = System.nanoTime();
    
            synchronized (lock1)
            {
                if (min_time == Long.MAX_VALUE)
                {
                    min_time = max_time = t;
                    min_name = max_name = Thread.currentThread().getName();
                }
                else if (t < min_time)
                {
                    min_time = t;
                    min_name = Thread.currentThread().getName();
                }
                else
                {
                    max_time = t;
                    max_name = Thread.currentThread().getName();
                }
            }
        }
    
        public static void main(String[] args) throws InterruptedException
        {
            for (int i = 0; i < threads_count; i++)
            {
                new Thread()
                {
                    public void run()
                    {
                        test();
                    }
                }.start();
            }
            Thread.sleep(1000);
            print_result();
    
            for (int i = 0; i < threads_count; i++)
            {
                new Thread()
                {
                    public void run()
                    {
                        synchronized (lock1)
                        {
                            current_count++;
                            try
                            {
                                lock1.wait();
                            }
                            catch (InterruptedException e) {}
                        }
    
                        test();
                    }
                }.start();
            }
    
            synchronized (lock1)
            {
                while (current_count < 10)
                    lock1.wait(100);
    
                lock1.notifyAll();
            }
    
            Thread.sleep(1000);
    
            print_result();
        }
    
        private static void print_result()
        {
            System.out.println("Delta = " + (max_time - min_time));
            System.out.println("min_name = " + min_name);
            System.out.println("max_name = " + max_name);
            System.out.println();
    
            min_time = Long.MAX_VALUE;
            max_time = Long.MIN_VALUE;
            min_name = "";
            max_name = "";
        }
    }


    что имеем в результате....

    я получаю примерно такие значения

    Delta = 923022
    min_name = Thread-9
    max_name = Thread-0
    
    Delta = 637511
    min_name = Thread-19
    max_name = Thread-10


    Delta = 4899226
    min_name = Thread-0
    max_name = Thread-3
    
    Delta = 634158
    min_name = Thread-19
    max_name = Thread-10


    выводы

    1) Как и предполагалось потоки стартуют так, как того захочет шедулер, порядок создания потоков и момент их реального старта никак не коррелирует. Нет понятие раньше позже, о чем я и писал.

    2)действительно, при запуске всех потоков с синхронизацией через барьер разница между моментом старта первого и последнего стартующего меньше. То есть потоки стартуют более одновременно, чем без барьера.
    НО! и это важно. Эту разницу можно заметить только на уровне наносекунд. Что для теста производительности пула и просто большинства тестов, совершенно не существенно. Там учет происходит с сотнях милисекунд.
    Re[11]: пулл обектов. как оно на самом деле....
    От: Blazkowicz Россия  
    Дата: 14.08.07 08:56
    Оценка:
    Здравствуйте, Shabi, Вы писали:

    S>Эх, хорошо.... пока такой код будет обнаруживаться в проектах...я без работы не останусь.

    Работа в области обфускации исходного кода?

    S>Все понимаю, новые JDK, новомодные патерны...но для чего так код усложнять-то...?

    S>Возможно, что это дело вкуса...не буду спорить.
    Возможно, что недостаток знания java.util.concurrent.* и пр. вызывает непонимаение? Я как-то не заметил что код приведенный ниже читается сильно лучше.

    S>В моем исполнении все тоже самое будет выглядить так...

    Все ясно. Консерватизм и велосипеды ещё инкто неотменял. Свое ведь всегда лучше.

    S>выводы


    S>1) Как и предполагалось потоки стартуют так, как того захочет шедулер, порядок создания потоков и момент их реального старта никак не коррелирует. Нет понятие раньше позже, о чем я и писал.

    Но это все никак не связано с тем что время затрачиваемое на создание потока в Вашем примере влияет на результаты теста. На что сразу и было указано. А Вы сразу про "шедулер", "порядок"...

    S>2)действительно, при запуске всех потоков с синхронизацией через барьер разница между моментом старта первого и последнего стартующего меньше. То есть потоки стартуют более одновременно, чем без барьера.

    S>НО! и это важно. Эту разницу можно заметить только на уровне наносекунд. Что для теста производительности пула и просто большинства тестов, совершенно не существенно. Там учет происходит с сотнях милисекунд.
    Ну, начинается. Нет никаких абстрактных сотен миллисекунд. Есть тесты, есть погрещность. Увеличь число потоков набежит и сотня и вообще сколько надо.
    Re[12]: пулл обектов. как оно на самом деле....
    От: Shabi  
    Дата: 14.08.07 10:37
    Оценка:
    Здравствуйте, Blazkowicz, Вы писали:

    S>>В моем исполнении все тоже самое будет выглядить так...

    B>Все ясно. Консерватизм и велосипеды ещё инкто неотменял. Свое ведь всегда лучше.

    это опять таки дело вкуса....

    S>>выводы


    S>>1) Как и предполагалось потоки стартуют так, как того захочет шедулер, порядок создания потоков и момент их реального старта никак не коррелирует. Нет понятие раньше позже, о чем я и писал.

    B>Но это все никак не связано с тем что время затрачиваемое на создание потока в Вашем примере влияет на результаты теста. На что сразу и было указано.

    еще раз... Это мягко скажем...заблуждение, считать что первым запускаемый поток находится в превелигированном положении. Ибо далеко не факт, что он стартонет первым. Перечитайте там Денис именно об этом пишет.

    Также тест неправильный еще и из-за того, что потоки, выполняющие test1() стартуют раньше потоков, выполняющих test2() ==> вторая группа работает в режиме более жесткой конкуренции за системные ресурсы.


    ведь это очевидное заблуждение . Если совсем невериться, так переставте местами...сначала пусть вызываются test2() а потом test1() и получите такой же результат что и раньше...

    и....ни на какие результаты влияния нет. ибо все подсчеты происходят внутри потока.

    B>Ну, начинается. Нет никаких абстрактных сотен миллисекунд. Есть тесты, есть погрещность. Увеличь число потоков набежит и сотня и вообще сколько надо.


    вот тут я согласен!!!! только совсем от реальности отрываться нестоит...
     
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.